레이블이 정렬인 게시물을 표시합니다. 모든 게시물 표시
레이블이 정렬인 게시물을 표시합니다. 모든 게시물 표시

2010년 10월 25일 월요일

아이폰 사진 보관함 정렬 순서 바꾸기

아이폰에서 사진을 보여주는 순서는 파일명 순이 아니다. (iOS 4.x 기준)
순서는 다음과 같은 기준으로 이루어진다.

1. Exif에 기록된 편집일자
2. Exif에 기록된 생성일자
3. 파일 수정일자
4. 파일 생성일자

이러한 순서는 디지털 카메라로 찍은 사진만 있을 경우엔 여러모로 도움이 된다.
다양한 카메라로 찍은 사진을 저장하기만 하면 시간 순으로 보여주기 때문이다.

그런데, PNG 파일과 JPEG 파일을 같이 보관하고, 다양한 편집을 한 결과를 같이 보관할 때는 문제가 좀 있다.
예를 들면, Darth.jpg와 이를 편집한 Darth_frame.jpg를 같이 저장하면 두 이미지는 같이 보여지지 않는다.


즉, 파일명의 순서와는 무관하기 때문에 위에서 보는 것과 같이 관련된 이미지를 함께 볼 수가 없는 것이다.
아이폰에서 관련된 이미지를 함께 보려면 파일의 생성/편집 일자와 Exif 일자를 몽땅 바꾸는 방법 밖에 없다.

이런 작업을 일괄적으로 할 수 있도록 간단하게 프로그램을 하나 만들었다.


이 프로그램은 아이폰에서 사진을 동기화할 폴더를 지정한 뒤에 원하는 순서대로 배치를 하고 날짜정보를 수정한다.
폴더 지정은 아이튠즈에 동기화하는 폴더를 에디트 박스에 드래그 앤 드롭만 하면 된다.
그리고, 다음과 같은 정렬 순서를 지원한다.

1. 날짜 순 (iOS 4.x 기본값)
2. 폴더 및 파일명 순 (폴더 순으로 정렬한 뒤 파일명 순으로 정렬)
3. 파일명 순 (폴더에 무관하게 파일명 순으로 정렬)

원하는 순서로 배치한 뒤에 Apply! 버튼을 클릭하면 Exif 정보를 포함한 파일의 날짜를 일괄적으로 수정해준다.
(현재 날짜와 시간을 기준으로 1초씩 차이가 나도록 수정)

이렇게 수정한 뒤 사진 폴더를 다시 동기화 시키면 아래 캡쳐화면처럼 관련 이미지들을 함께 볼 수 있다.


이 프로그램은 아래에서 다운받을 수 있다.


2008년 1월 30일 수요일

추억4-부록. MSX-BASIC으로 작성해본 그 프로그램

추억4. 컴퓨터 경진대회 참가에서 적었던 프로그램을 MSX-BASIC으로 만들어봤습니다.

paraMSX과 같은 실제의 클럭과 유사하게 동작하는 에뮬레이터가 많기때문에 실행은 물론, 시간이 얼마나 걸리는가도 확인해볼 수 있습니다.

10번 실행해보니 31초가 걸리는군요. 1번3.1초씩 걸렸군요.

100 ' create 16 random numbers
110 I=RND(-TIME)
120 DIM RN(16)
130 FOR I=0 TO 15
140 RN(I)=INT(RND(1)*100)
150 NEXT I
160 ' sorting
170 C=16
180 ' do-loop
190 C=C-1
200 SW=0
210 FOR I=0 TO C-1
220 IF (RN(I)>RN(I+1)) THEN TE=RN(I):RN(I)=RN(I+1):RN(I+1)=TE:SW=1
230 NEXT I
240 IF SW<>0 GOTO 180
250 ' while
260 ' print
270 DIM CR(16)
280 FOR I=0 TO 15
290 READ CR(I)
300 NEXT I
310 FOR I=0 TO 15
320 PRINT USING "## ";RN(CR(I));
330 IF I MOD 4 = 3 THEN PRINT
340 NEXT I
350 'CROSS data
360 DATA 0, 1, 3, 6
370 DATA 2, 4, 7,10
380 DATA 5, 8,11,13
390 DATA 9,12,14,15

같은 동작을 하는 프로그램을 VC++로 돌려보니 0ms 걸렸습니다. (GetTickCount()로 확인했습니다)
역시 기술의 발전은 놀랍습니다.

동작화면을 캡쳐한 것은 아래를 열면 볼 수 있습니다. 옛 추억에 한 번 빠져 봅시다… ^^;; (개콘)

MSX 화면에서 캡쳐한 것 보기..



추억4. 컴퓨터 경진대회 참가

초등학교 다닐 때 컴퓨터 경진대회 도예선에 참가하게 되었습니다.

도예선을 통과하면 전국대회에 갈 수 있으니, 어린 마음에 엄청 기대를 하고 갔습니다.

사용자 삽입 이미지

MSX BASIC 실행화면입니다

당시 필기시험은 없고, 실기시험만 있었는데, BASIC을 이용해서 주어진 5 문제를 해결하면 되는 형식이었습니다.


(요즘 정보처리 관련 자격증 시험 보면 문제은행 달달 외면 되는 필기시험으로 도배되어 있는데, 차라리 이 때의 시험이 더 나았다고 봅니다)

당시 처음 배웠던, 1부터 n까지의 합을 구하는 비장의 공식
S = n(n+1)/2 까지 동원해가며 4 문제를 성공적으로 풀었습니다.




마지막 5번 문제는 16개의 난수를 생성한 뒤에 이를 오름차순으로 정렬하고 나서 대각선 방향으로 배열해서 출력하는 문제였습니다.

즉, 난수를 생성, 정렬한 뒤에 아래와 같은 순서로 출력하면 되는 것입니다.

1 2 4 7
3 5 8 11
6 9 12 14
10 13 15 16

이 코드를 C로 작성하면 아래와 같이 됩니다.

sort는 비겁하게 내장 quick sort 알고리즘을 사용했습니다.

   1: #include <stdio.h>
   2: #include <stdlib.h>
   3: #include <time.h>
   4:  
   5: #define COUNT 16
   6:  
   7: int icompare( const void *arg1, const void *arg2 )
   8: {
   9:     return *(int *)arg1 - *(int *)arg2;
  10: }
  11:  
  12: int main(int argc, char* argv[])
  13: {
  14:     srand( (unsigned)time( NULL ) );
  15:  
  16:     int randoms[COUNT];
  17:     int i;
  18:  
  19:     // 16개의 난수 생성
  20:     for (i=0; i<COUNT; i++)
  21:     {
  22:         randoms[i] = rand() % 100;
  23:     }
  24:  
  25:     //정렬
  26:     qsort((void*)randoms, COUNT, sizeof(int), icompare);
  27:  
  28:     //출력
  29:     const int CROSS[] = {
  30:          0,  1,  3,  6,
  31:          2,  4,  7, 10,
  32:          5,  8, 11, 13,
  33:          9, 12, 14, 15
  34:     };
  35:  
  36:     for (i=0; i<COUNT; i++)
  37:     {
  38:         printf("%02d ", randoms[CROSS[i]]);
  39:         if ((i & 3) == 3) printf("\n");
  40:     }
  41:  
  42:     return 0;
  43: }

지금 보면 별 것 아닌 개념이지만, 당시에 초등학생이 이해하기에는 너무 복잡한 개념이었습니다.

정렬도 겨우 이해해서 짜는 마당에  저런 대각선 방향 출력이라니요…
(당시에는 문제 자체를 이해하지 못했습니다)

시험 감독관 선생님께서 보기에 답답하셨는지, 다른 것은 다 맞는데 이것만 틀렸으니까 다시 풀어보라고 친절하게 말씀해주시는 바람에 이 문제만 틀린 것은 알게 됐는데, 당시에는 왜 틀렸는지 몰랐습니다.

게다가 왜 정렬한 뒤에 이런 (쓸데없는!) 형태로 출력하는지도 몰랐고요.
그러다, 좀 더 철이 들고 공부를 하고 나서야 저 출력의 의미를 깨달을 수 있었습니다.

MPEG1에서 데이터 압축시 64개의 데이터를 저런 순서로 나열해서 FFT 연산을 수행합니다)

결국, 이 문제를 풀지 못해 도예선을 통과하지 못하고, 일장춘몽으로 끝나고 말았습니다. 휴~


덧1. 지금 저 코드를 BASIC으로 작성하지는 못하겠고, 그 때의 기분을 느껴본다는 생각으로 내장 quick sort 대신 bubble sort를 작성해서 끼워넣어봤습니다. 아래와 같습니다.

   1: #include <stdio.h>
   2: #include <stdlib.h>
   3: #include <time.h>
   4:  
   5: #define COUNT 16
   6:  
   7: int main(int argc, char* argv[])
   8: {
   9:     srand( (unsigned)time( NULL ) );
  10:  
  11:     int randoms[COUNT];
  12:     int i;
  13:  
  14:     // 16개의 난수 생성
  15:     for (i=0; i<COUNT; i++)
  16:     {
  17:         randoms[i] = rand() % 100;
  18:     }
  19:  
  20:     //정렬
  21:     int count = COUNT;
  22:     bool swapped;
  23:     do 
  24:     {
  25:         count--;
  26:         swapped=false;
  27:         for (i=0; i<count; i++)
  28:         {
  29:             if (randoms[i]>randoms[i+1])
  30:             {
  31:                 randoms[i]^=randoms[i+1]^=randoms[i]^=randoms[i+1];
  32:                 swapped=true;
  33:             }
  34:         }
  35:     } while(swapped);
  36:     
  37:     //출력
  38:     const int CROSS[] = {
  39:          0,  1,  3,  6,
  40:          2,  4,  7, 10,
  41:          5,  8, 11, 13,
  42:          9, 12, 14, 15
  43:     };
  44:  
  45:     for (i=0; i<COUNT; i++)
  46:     {
  47:         printf("%02d ", randoms[CROSS[i]]);
  48:         if ((i & 3) == 3) printf("\n");
  49:     }
  50:  
  51:     return 0;
  52: }

덧2. 문제가 5 문제였는지는 확실하지 않습니다. 대략의 기억입니다. 어쨌든, 저 문제 외에는 다 풀었습니다.
       감독관 선생님께서 분명히 말씀해주셨습니다. ^^;;;

덧3. 이 글은 Windows Live Writer로 작성해봤습니다. 코드 입력은 Code Snippet plugin을 사용했구요.