GDI+ 에서는 각 이미지에 들어가는 meta 정보를 포인터 구조체로 가져 올 수 있습니다.
이 meta 정보에는 JPEG 의 EXiF 도 포함되며 꽤 많은 정보를 가져다 쓸 수 있습니다.
이 meta 정보 구조체의 구조는 다음과 같습니다.
이 구조체의 포인터를 이용해서 쓸수 있는 것이 바로 GetPropertySize(잡을 버퍼 크기,프로퍼티 카운트); 가 되겠습니다.
원래 C/C++ 를 위해 만들어 진 것이라 델파이에서 바로 쓰기엔 조금 번거러움이 있으나 , Pointer() 함수에 대해 이해도가 있다면 쉽게 접근 할 수 있습니다. (C 에서 쓰는것과 같게 사용이 가능하다는 것 입니다 ^^)
물론 이 방법으로 GUID 로 얻어 오는 CODEC 정보도 함께 처리 할 수 있게 됩니다.
실제 제가 사용하는 코드 일부 입니다.
썸네일 이미지를 만들면서 메타 정보를 함께 얻어 오는 부분 입니다.
thumbImg 는 TGPImage 객체 이며, 이미 이미지를 load 해서 썸네일 생성을 특정 DC에 그리길 완료 한 상태 입니다.
먼저 GetPropertySize(metaSize,metaCount); 로 메타정보의 크기와 정보구조체의 길이를 가져 옵니다.
그런다음 getMem() 으로 메모리를 ppID 에 할당 하여 GetAllPropertyItems() 로 모두 들고 옵니다.
이미 구해진 길이 metaCount 만큼 count 를 for 로 증가 시키면서 제가 따로 만든 구조체에 메타 정보를 쓰기 쉽게 집어 넣습니다.
이때 각 배열 구조체를 C 나 C++ 처럼 사용할 수 없기 때문에 ppID 와 동일한 구조체 포인터인 pProperty 에 해당 포인터를 대입하여 각 구조체 내의 멤버들을 접근 하게 되는 방법이 다음과 같았습니다.
pProperty := Pointer(DWORD(ppID) + sizeof(PropertyItem)*count);
이 방법은 C 나 C++ 에서는 ppID[count]->멤버 ... 접근과 동일하게 됩니다. (조금 번거러운 부분이 발생 하지만 서로 다른 언어의 접근 차이에서 발생하는 차이 입니다 :)
그래서 실제 메타정보는 ppID 에 들어 가 있게 되지만 해당 메타정보들의 접근은 pProperty 포인터로 하게 됩니다.
일단 저는 각 프로퍼티의 정보를 WideString 에 우겨 넣고 있습니다만..
size 를 알게 되면 각 배열에 들어간 정보를 다시 다른 형태의 데이터로 가공이 가능하기 때문에 편리하게 쓰는 방법 입니다.
이 meta 정보에는 JPEG 의 EXiF 도 포함되며 꽤 많은 정보를 가져다 쓸 수 있습니다.
이 meta 정보 구조체의 구조는 다음과 같습니다.
이 구조체의 포인터를 이용해서 쓸수 있는 것이 바로 GetPropertySize(잡을 버퍼 크기,프로퍼티 카운트); 가 되겠습니다.
원래 C/C++ 를 위해 만들어 진 것이라 델파이에서 바로 쓰기엔 조금 번거러움이 있으나 , Pointer() 함수에 대해 이해도가 있다면 쉽게 접근 할 수 있습니다. (C 에서 쓰는것과 같게 사용이 가능하다는 것 입니다 ^^)
물론 이 방법으로 GUID 로 얻어 오는 CODEC 정보도 함께 처리 할 수 있게 됩니다.
실제 제가 사용하는 코드 일부 입니다.
썸네일 이미지를 만들면서 메타 정보를 함께 얻어 오는 부분 입니다.
thumbImg 는 TGPImage 객체 이며, 이미 이미지를 load 해서 썸네일 생성을 특정 DC에 그리길 완료 한 상태 입니다.
먼저 GetPropertySize(metaSize,metaCount); 로 메타정보의 크기와 정보구조체의 길이를 가져 옵니다.
그런다음 getMem() 으로 메모리를 ppID 에 할당 하여 GetAllPropertyItems() 로 모두 들고 옵니다.
이미 구해진 길이 metaCount 만큼 count 를 for 로 증가 시키면서 제가 따로 만든 구조체에 메타 정보를 쓰기 쉽게 집어 넣습니다.
이때 각 배열 구조체를 C 나 C++ 처럼 사용할 수 없기 때문에 ppID 와 동일한 구조체 포인터인 pProperty 에 해당 포인터를 대입하여 각 구조체 내의 멤버들을 접근 하게 되는 방법이 다음과 같았습니다.
pProperty := Pointer(DWORD(ppID) + sizeof(PropertyItem)*count);
이 방법은 C 나 C++ 에서는 ppID[count]->멤버 ... 접근과 동일하게 됩니다. (조금 번거러운 부분이 발생 하지만 서로 다른 언어의 접근 차이에서 발생하는 차이 입니다 :)
그래서 실제 메타정보는 ppID 에 들어 가 있게 되지만 해당 메타정보들의 접근은 pProperty 포인터로 하게 됩니다.
일단 저는 각 프로퍼티의 정보를 WideString 에 우겨 넣고 있습니다만..
size 를 알게 되면 각 배열에 들어간 정보를 다시 다른 형태의 데이터로 가공이 가능하기 때문에 편리하게 쓰는 방법 입니다.