상세 컨텐츠

본문 제목

FreeImage Library 를 이용하여 이미지 따로 저장 관련

프로그래밍 관련/3D,2D DRAW 관련

by AlrepondTech 2020. 9. 15. 18:03

본문

반응형

 

 

=================================

=================================

=================================

 

 

 

출처: http://m.blog.naver.com/sogangori/220701976219

FreeImage는 리눅스와 윈도우즈 운영체제 양쪽에서 똑같이 사용할 수 있는 C++ 이미지 처리 라이브러리 입니다

NVidia 의 이미지 처리 CUDA 샘플 프로젝트들이 FreeImage 라이브러리를 사용합니다.

그동안 사용해 보니 좋은 라이브러리라고 생각됩니다.

윈도우 OS 의 경우 32bit와 64 bit 의 .lib 파일이 다르므로 64bit 프로젝트를 사용할때는 64bit 용 .lib를 사용해야 합니다.

http://freeimage.sourceforge.net/

 

윈도우 운영체제에서 사용하기

인스톨 방법입니다. 이 방법을 사용하면 .lib 파일을 가지고 다니는 등의 필요가 없이 가장 편리하게 사용할 수 있습니다.

 

1) 다운로드 받습니다. -  FreeImage3170.zip

2) 압축 풀고 프리이미지 폴더로 이동합니다 - cd FreeImage install folder

3) 컴파일 합니다 - make 

 

............

strenc.c:(.text+0x12cd): warning: the use of `tmpnam' is dangerous, better use `mkstemp'
mkdir -p Dist
cp *.a Dist/
cp *.so Dist/
cp Source/FreeImage.h Dist/
make[1]: Leaving directory `/home/way/FreeImage'

4) 인스톨합니다 - sudo make install 

 

way@way-All-Series:~/FreeImage$ sudo make install
make -f Makefile.gnu install 
make[1]: Entering directory `/home/way/FreeImage'
install -d //usr/include //usr/lib
install -m 644 -o root -g root Source/FreeImage.h //usr/include
install -m 644 -o root -g root libfreeimage.a //usr/lib
install -m 755 -o root -g root libfreeimage-3.17.0.so //usr/lib
ln -sf libfreeimage-3.17.0.so //usr/lib/libfreeimage.so.3
ln -sf libfreeimage.so.3 //usr/lib/libfreeimage.so    
make[1]: Leaving directory `/home/way/FreeImage'

5) 필요없는 파일들을 정리해 줍니다 - make clean

 

Installation 
------------ 
Note: You will need to have root privileges in order to install the library in the /usr/lib directory. 
The installation process is as simple as this :  
1) Enter the FreeImage directory 
2) Build the distribution :  
make 
make install 
3) Clean all files produced during the build process 
make clean

 

설치가 완료되었습니다. 빌드명령에 -lfreeimage  를 추가해 주기만 하면 됩니다.

You should be able to link progams with the -lfreeimage option after the library is compiled and installed.  
You can also statically link with libfreeimage.a.

 

압축 파일 내에는 Renux 용 샘플이 있습니다만 다른 추가 라이브러리를 필요로 하기 때문에 사용할 수가 없었습니다.

FreeImage 만 가지고 이미지 읽기 테스트를  했습니다.

 

예제 1 )  이미지 파일 읽기

#include <stdio.h>
#include <FreeImage.h>
#include <string.h>

int main(void) {
    printf("Hello C++\n");

    const char* imagePath = "/tmp/n2.png";
    FreeImage_Initialise(TRUE);

    FIBITMAP *dib = FreeImage_Load(FIF_PNG, imagePath, PNG_DEFAULT);
    return 0;
}

빌드하기 : sudo gcc -o main main.cpp -lfreeimage
 

예제 2 ) Gray/Color 이미지 자동으로 구분해서 읽기

#include <stdio.h>
#include <FreeImage.h>
#include <string.h>

int main(int argc, char** argv) {
    printf("argc = %d \n",argc);
    char* imagePath = "/tmp/n2.png";

    if(argc>1){
        for(int i=0; i<argc; i++){
            printf("argv[%d] = %s \n",i,argv[i]);
        }
        imagePath = argv[1];
    }

    printf("imagePath = %s\n",imagePath);
    FreeImage_Initialise(TRUE);
    FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(imagePath);
    FIBITMAP *dib = FreeImage_Load(fif, imagePath, PNG_DEFAULT);
    int width = FreeImage_GetWidth(dib);
    int height = FreeImage_GetHeight(dib);
    int bpp = FreeImage_GetBPP(dib);

    printf("width,height = %d x %d , bpp = %d\n", width,height,bpp);

    BYTE *ptr = FreeImage_GetBits(dib);
    if ( ptr == NULL )
    {
        printf("pixel Null\n");
    }

    RGBQUAD color;
  BYTE gray=0;
    for (int y = 0; y < FreeImage_GetHeight(dib); y++) {
        for (int x = 0; x < FreeImage_GetWidth(dib); x++) {
            if(bpp==8){
                FreeImage_GetPixelIndex(dib, x, y, &gray);
                printf("%d",gray);
            }else{
                FreeImage_GetPixelColor(dib, x, y, &color);
                printf("%d ",color.rgbBlue);
            }
        }
        printf("\n");
    }
    FreeImage_Unload(dib);
    return 0;
}

빌드하기 : sudo gcc -o ImageReadUsingFreeImage ImageReadUsingFreeImage.cpp -lfreeimage
실행하기 : ./ImageReadUsingFreeImage
실행하기 : ./ImageReadUsingFreeImage /tmp/n5.png
 

예제 3 ) 인자(-print)를 받아서 이미지 픽셀 정보 출력하기 

#include <stdio.h>
#include <FreeImage.h>
#include <string.h>

int main(int argc, char** argv) {
    printf("argc = %d \n",argc);
    char* imagePath = "/tmp/n2.png";
    char printCommand[] = "-print";
    bool isPrintPixel = false;

    if(argc>=2){
        for(int i=0; i<argc; i++){
            printf("argv[%d] = %s \n",i,argv[i]);
        }
        imagePath = argv[1];
        if(argc>=3 && strcmp(argv[2],printCommand)==0){
            printf("arg[2] is %s. Print Pixels \n",argv[2]);
            isPrintPixel=true;
        }
    }

    printf("\n");
    printf("imagePath = %s\n",imagePath);
    FreeImage_Initialise(TRUE);
    FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(imagePath);
    FIBITMAP *dib = FreeImage_Load(fif, imagePath, PNG_DEFAULT);
    int width = FreeImage_GetWidth(dib);
    int height = FreeImage_GetHeight(dib);
    int bpp = FreeImage_GetBPP(dib);

    printf("width,height = %d x %d , bpp = %d\n", width,height,bpp);

    BYTE *ptr = FreeImage_GetBits(dib);
    if ( ptr == NULL )
    {
        printf("pixel Null\n");
    }

    RGBQUAD color;
  BYTE gray=0;
    for (int y = 0; y < FreeImage_GetHeight(dib); y++) {
        for (int x = 0; x < FreeImage_GetWidth(dib); x++) {
            if(bpp==8){
                FreeImage_GetPixelIndex(dib, x, y, &gray);
                if(isPrintPixel)printf("%d",gray);
            }else{
                FreeImage_GetPixelColor(dib, x, y, &color);
                if(isPrintPixel)printf("%d ",color.rgbBlue);
            }
        }
        if(isPrintPixel)printf("\n");
    }
    FreeImage_Unload(dib);
    return 0;
}

빌드하기 : sudo gcc -o ImageReadUsingFreeImage ImageReadUsingFreeImage.cpp -lfreeimage
실행하기 : ./ImageReadUsingFreeImage
실행하기 : ./ImageReadUsingFreeImage /tmp/n5.png
실행하기 : ./ImageReadUsingFreeImage /tmp/n5.png -print
실행하기 : ./ImageReadUsingFreeImage /tmp/ioi.jpg
 

예제 4) 픽셀 데이터를 배열로 저장하기 memcpy 

         픽셀 데이터를 배열에 저장하는 것이 필요해서 FreeImage를 사용하는 경우가 많겠죠. 

         BYTE는 unsigned char로 FreeImage.h  typedef unsigned char BYTE;  되어 있습니다

#include <stdio.h>

#include <FreeImage.h>

#include <string.h>

#include <malloc.h>


int main() {

    char * imagePath = "./n9.png";

    printf("imagePath = %s\n", imagePath);

    FreeImage_Initialise(TRUE);

    FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(imagePath);

    FIBITMAP * dib = FreeImage_Load(fif, imagePath, PNG_DEFAULT);

    int width = FreeImage_GetWidth(dib);

    int height = FreeImage_GetHeight(dib);

    int bpp = FreeImage_GetBPP(dib);

    printf("width,height = %d x %d , bpp = %d\n", width, height, bpp);

    BYTE * ptr = FreeImage_GetBits(dib);

    if (ptr == NULL)

    {

        printf("pixel Null\n");

    }

    unsigned int dibSize = FreeImage_GetDIBSize(dib);

    printf("dibSize %d\n", dibSize);

    BYTE * src = (BYTE * ) malloc(width * height);

    memcpy(src, ptr, width * height);

    RGBQUAD color;

    BYTE gray = 0;

    for (int y = 0; y < FreeImage_GetHeight(dib); y++) {

        for (int x = 0; x < FreeImage_GetWidth(dib); x++) {

            if (bpp == 8) {

                gray = src[y * width + x];

                if (gray == 0) printf(" ");

                else printf("%d", gray);

            } else {

                FreeImage_GetPixelColor(dib, x, y, & color);

                printf("%d ", color.rgbBlue);

            }

        }

        printf("\n");

    }

    printf("\n");

    for (int y = 0; y < FreeImage_GetHeight(dib); y++) {

        for (int x = 0; x < FreeImage_GetWidth(dib); x++) {

            if (bpp == 8) {

                FreeImage_GetPixelIndex(dib, x, y, & gray);

                if (gray == 0) printf(" ");

                else printf("%d", gray);

            } else {

                FreeImage_GetPixelColor(dib, x, y, & color);

                printf("%d ", color.rgbBlue);

            }

        }

        printf("\n");

    }

    FreeImage_Unload(dib);

    return 0;

}

 

예제 4) 배열을 Gray 이미지로 저장하기

void FreeImageSetup() {
    const char * path = "ftest.bmp";
    int w = 128;
    int h = 128;
    int c = 1;
    FIBITMAP * bitmap = FreeImage_Allocate(w, h, 1);
    BYTE * src = new BYTE[w * h * c];
    for (int i = 0; i < w * h; i++) {
        src[i] = i;
    }
  
    FIBITMAP * Image = FreeImage_ConvertFromRawBits(src, w, h, c, 8, 0, 0, 0, false);
    FreeImage_Save(FIF_PNG, Image, "src.png", 0);
    FreeImage_Unload(Image);
}

 

예제 5) 배열을 RGB로 저장하기

void FreeImageSetup()

{

    const char * path = "color.bmp";

    int w = 16;
    int h = 16;
    int c = 3;

    FIBITMAP * bitmap = FreeImage_Allocate(w, h, c);

    BYTE * src = new BYTE[w * h * c];

    for (int i = 0; i < w * h; i++) {

        src[i * c + 0] = i; //B

        src[i * c + 1] = i; //G

        src[i * c + 2] = 200; //R

    }

    FIBITMAP * Image = FreeImage_ConvertFromRawBits(src, w, h, w * c, 8 * c, 0, 0, 0, false);

    FreeImage_Save(FIF_BMP, Image, "src.png");

    FreeImage_Unload(Image);

}

예제 6) 배열을 이미지로 저장하기 

        FreeImage 로 이미지파일을 읽으면 RGBA 4채널로 읽습니다. 

       그래서 아래예제에서 Alpha 채널을 제외한 RGB만 뻈습니다. 

       배열에 RGB 데이터가 저장되어 있는 상황에서 이미지를 저장하는 예제입니다.

printf("imagePath = %s\n", path);
FreeImage_Initialise(TRUE);
FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(path);
FIBITMAP * dib = FreeImage_Load(fif, path, PNG_DEFAULT);
int width = FreeImage_GetWidth(dib);
int height = FreeImage_GetHeight(dib);
int pitch = FreeImage_GetPitch(dib);
int bpp = FreeImage_GetBPP(dib);
printf("width,height = %d x %d pitch=%d, bpp = %d\n", width, height, pitch, bpp);

int channel = 3;
BYTE * ptr = FreeImage_GetBits(dib);
BYTE * src = (BYTE * ) malloc(width * height * channel);
for (int i = 0; i < width * height; i++) {
    src[i * 3 + 0] = ptr[i * 4 + 0];
    src[i * 3 + 1] = ptr[i * 4 + 1];
    src[i * 3 + 2] = ptr[i * 4 + 2];
}
FIBITMAP * Image = FreeImage_ConvertFromRawBits(src, width, height, width * channel, 8 * channel, 0, 0, 0, false);
FreeImage_Save(FIF_PNG, Image, "src.png", 0);
FreeImage_Unload(Image);
어떤 이미지들은 위의 복사가 안되는 경우도 있습니다.아래 처럼 넣어줍니다.BYTE * src = (BYTE * ) malloc(width * height * channel);
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        int srcIndex = y * pitch + x * 3;
        int dstIndex = y * width * channel + x * 3;
        src[dstIndex + 0] = ptr[srcIndex + 0];
        src[dstIndex + 1] = ptr[srcIndex + 1];
        src[dstIndex + 2] = ptr[srcIndex + 2];
    }
}

 

윈도우 운영체제에서 사용하기

윈도우즈 운영체제에서는 Visual Studio 를 이용하겠습니다. 

 

1. C++ 프로젝트를 생성

2. 프로젝트 속성 페이지 - 구성 속성- VC++ 디렉토리 - 포함 디렉터리 && 라이브러리 디렉터리에 

각각 FreeImage.h와 FreeImage.lib 가 있는 폴더를 추가합니다.

이 두 파일은 같이 있어요.

 

2. 프로젝트 폴더에 FreeImage.dll을 복사합니다.

위의 소스 파일을 똑같이 사용합니다.

혹시 미리 컴파일된 헤더쪽에 문제가 있어서 컴파일이 되지 않는 다면

프로젝트 속성페이지- C/C++ - 미리 컴파일된 헤더 - 미리 컴파일된 헤더 - 미리 컴파일된 헤더 사용 안 함 을 선택하세요.

2-2. 프로젝트 폴더에 FreeImage.dll 을 매번 저장하기가 귀찮다면 C:/Windows/SysWOW64 에 FreeImage.dll 을 저장합니다.

 

 

 

 

 

 

 

반응형

 

728x90

 

 

=================================

=================================

=================================

 

 

 

출처: http://noteroom.tistory.com/entry/FreeImage-%EA%B8%B0%EB%B3%B8-%EC%82%AC%EC%9A%A9%EB%B2%95

 

FreeImage 기본적인 사용 중

파일을 읽은 후 이 것을 윈도우 창에 뿌려보는 작업을 정리해 보려한다.

 

1. 일단 FreeImage 라이브러리 파일을 다운받는다.

소스와 win32용으로 미리 빌드된 바이너리가 있는데, 굳이 컴파일 할 필요는 없으므로 바이너리를 받았다.

(FreeImage 를 사용해보려는 것이지 컴파일이 목적은 아니다. libpng 를 wince 에 포팅해보았지만.. 삽질일 뿐이다.

포팅은 성공했지만 프로젝트에서 png 파일을 쓸 일이 없어 결국 실제 사용하지도 않았다.)

 

2. FreeImage.h, FreeImage.lib 은 적당한 라이브러리 디렉토리에 옮기고,

FreeImage.dll 은 미리 windows\system(혹은 windows\system32) 에 옮겨 두었다.

 

3. 기본 작업

헤더를 포함시키고 (본인 디렉토리 패스 기준임..), 프로젝트 설정에 라이브러리도 추가.

#include "../LIB/FreeImage.h"

 

간단히 테스트용도이므로 전역에 벡터하나 생성

vector<FIBITMAP*> g_fibmp;

 

초기화/해제 작업 코드 삽입

FreeImage_Initialise() / FreeImage_DeInitialise()

 

4. 파일 로드 코드

FIBITMAP* fibmp;

FREE_IMAGE_FORMAT fiformat = FIF_UNKNOWN;

 

// 포멧을 알아낸다.

fiformat = FreeImage_GetFIFFromFilename(filename);
if(FIF_UNKNOWN != fiformat) {
    // 로드한다.
    fibmp = FreeImage_Load(fiformat, filename);
    g_fibmp.push_back(fibmp);
}

 

매우 간단하게 로드된다.

 

5. 뿌려보자.

HBITMAP hBmp;
FIBITMAP * fibmp;
fibmp = g_fibmp[0];
int cx,
cy;
cx = FreeImage_GetWidth(fibmp);
cy = FreeImage_GetHeight(fibmp);
BYTE * pData = FreeImage_GetBits(fibmp);
hBmp = CreateCompatibleBitmap(hdc, cx, cy);
SetDIBits(hdc, hBmp, 0, cy, pData, FreeImage_GetInfo(fibmp), DIB_RGB_COLORS);
DrawBitmap(hdc, 0, 0, hBmp);
DeleteObject(hBmp);

 

DI 비트맵을 작성후 이미지 데이터를 넣어주고 출력해주는 코드다.

DrawBitmap 함수는 winapi.co.kr 에서 가져온 것인데 그냥 인터넷에 널려있는 출력코드와

다른 것은 없다.

 

6. 해제시키자.

char buff[MAX_PATH];

for (int i = 0; i < g_fibmp.size(); ++i)

{

    sprintf(buff, "c:\\TestSave_%d.bmp", i);

    FreeImage_Save(FIF_BMP, g_fibmp[i], buff);

    FreeImage_Unload(g_fibmp[i]);

}

 

그냥 저장도 넣어봤다... 아주 잘된다.



출처: http://noteroom.tistory.com/entry/FreeImage-기본-사용법 [책읽는아이 낙서장]

 

 

=================================

=================================

=================================

 

 

출처: http://panboy.tistory.com/m/990

오늘 하루종일 이걸로 씨름했네요.

일반적인 이미지 파일들은 다 RGB죠. 

처음엔 GDI+를 이용해보려 했는데, GDI+는 MSDN의 포럼에서도 FreeImage를 사용하라고 되어 있어요. 
설마.. 되겠지 하고 한참 찾아봤는데 GDI+ 로는 CMYK에 관한 처리를 할 수 없습니다. 

다음은 예전에 써봐서 익숙한 CxImage를 이용해 보려 했는데,
xdp 아닌 곳에서  7.02 배포하는 건 뭥미? 암튼. 
xdp에서 6.0을 받아서 해봤는데, 
CxImage에서 CMYK 분판 인쇄(각각의 파일로 저장)하는 건 가능한데, 다시 CMYK로 저장하는 게 안되네요.
무조건 RGB로 변경됩니다. 
이거 뭔가 옵션이 있을 듯도 한데.. 찾지 못했어요.

그래서 MSDN 포럼에 나온대로 FreeImage를 사용하기로 했습니다. 
다행히 잘 되네요. 

FreeImage_Initialise();

char * szFilepath = "E:\\앞면.tif"; // 이 파일은 CMYK 파일이다. 
FREE_IMAGE_FORMAT fif = FIF_TIFF;

int flag = 0;
FIBITMAP * dib = NULL;

fif = FreeImage_GetFileType(szFilepath, TIFF_CMYK);
if (fif == FIF_UNKNOWN) {
    fif = FreeImage_GetFIFFromFilename(szFilepath);
}

if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
    dib = FreeImage_Load(fif, szFilepath, TIFF_CMYK);
}

if (!dib) {
    TRACE("이미지 로드 실패\n");
    return;
}

TRACE("FreeImagColorType = %d\n", FreeImage_GetColorType(dib));
int bpp = FreeImage_GetBPP(dib); // 여기서 32가 나와야 정상이다. 

char * szFilepath2 = "c:\\IDCard\\test.tif";
FreeImage_Save(fif, dib, szFilepath2, TIFF_CMYK);

FreeImage_Unload(dib);

FreeImage_DeInitialise();


이렇게  하면 CMYK로 읽어들이고 CMYK로 저장된다. 
오~!! 

 

 

 

=================================

=================================

=================================

 

 

출처: http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=47&MAEULNo=19&no=289055&ref=289037

vb에서 온라인 팩스를 화면상에 디스플레이 하고 출력할 수 있게끔 구현하려고 합니다.


팩스는 db에 .tif형식으로 저장되며, 이를 컨트롤 할 수 있는 툴이 필요합니다.


검색결과 .tif는 vb에서 제어할 수 있는 기본적으로 제공하는 그 어떠한 것들이 없었구요.


곧 개발을 해야 되는데,


상용 이미지 제어 툴중에 가장 많이들 사용하시고 기능도 많고 성능도 괜찮은 툴 있으면 추천 부탁드립니다.


그리고 판매처도 기재해 주시면 감사하겠습니다.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 FreeImage 나 Lead Tool 을 사용하면 Tif파일을 편집할 수 있습니다.

  보여줄때는 jpg파일이나 bmp파일로 변환하여 vb의 picturebox에 보여줄수도 있구요.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

일단 freeimage는 무료 dll 로 알고있습니다. 

  그래도 사용하실거면 좀 더 알아보신 후 사용하시구요, 

  어떤 기능들을 사용하실건지 적어주시면 가능한지 체크는 해 볼께여.


  hmm..  그리고 기능은 lead tool이 더 좋겠지요. 

  판매처는 인터넷 뒤져보니 몇군데 나오네여.

  
  저도 잘 모르는지라 원하시는 답변으론 부족한듯 하네요.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 freeimage 만으로 충분할거 같습니다.

  tif를 jpg나 bmp로 변환후 pictruebox에 출력하심 될거 같구요.

  tif파일은 내부적으로 페이지 개념으로 이미지를 가지고 있습니다.

  freeimage의 multipage관련 함수를 사용하면 됩니다.

 흠.. 근데 multilpage 부분은 제가 test를 못해본지라... test 해본 후 가능 여부 올려드릴께여.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

FreeImage는 Open Source입니다.

http://freeimage.sourceforge.net/

사이트에 FreeImage.dll 및 dll소스도 있습니다.

자신의 입맛에 맞게 DLL을 수정할 수도 있겠지만, 잘 만들어진 파일니 그냥 제공되는 함수만 사용하시면 될것 같습니다.

FreeImage말고도 GDI Plus를 이용하는 방법도 있습니다.

이건 왠만한 컴퓨터에는 다 깔려있을테니 별도의 Dll은 필요치 않습니다.

첨부하는 소스파일은 FreeImage와 GDI+를 이용한 각각의 간단한 예제입니다.

모듈에는 해당 프로그램에 필요한 모든 함수가 다 선언되어 있습니다.

참고하시고 좋은결과 얻으세요

 

※ 자료출처

   - FreeImage : 공식사이트

   - GDI+ : 하우투뱅크

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 ImageFile = FreeImage_OpenMultiBitmap(FIF_TIFF, _
             Text1(0).Text, False, True)

  k = FreeImage_GetPageCount(ImageFile)
  
  For i = 1 To k
    SplitImg = FreeImage_LockPage(ImageFile, i - 1)
        
    Call FreeImage_Save(FIF_TIFF, SplitImg, App.path & "\page" & i & ".tif")
    Call FreeImage_UnlockPage(ImageFile, i - 1, False)
  Next i

  Call FreeImage_CloseMultiBitmap(ImageFile)

  이 부분 참조하시면 될거 같습니다.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

=================================

=================================

=================================

 

 

반응형


관련글 더보기

댓글 영역