GDI + 를 사용하여 새 색상표를 .gif 파일을 저장하는 방법

기술 자료 번역 기술 자료 번역
기술 자료: 315780 - 이 문서가 적용되는 제품 보기.
모두 확대 | 모두 축소

이 페이지에서

요약

이 문서에서는 Microsoft Visual C# .NET 버전에 319061 참조하십시오.
이 문서에서는 Microsoft Visual Basic .NET 버전에 319591 참조하십시오.
다음 CompuServe 그래픽 GIF) 최대 색 테이블에 정렬된 256 색 디자인되었습니다. 일반적인 .gif 이미지 파일을 수정할 사용자 지정 색상표를 변경해야 합니다. 하지만 GDI + Image 개체를 편집하고 GIF 인코더를 사용하여 이미지를 저장할 전달되었을 때 결과 .gif 파일 하프톤 색상표를 포함합니다.

GIF 인코더를 사용하여 이미지 사용자 지정 색상표를 저장하려면 GDI + 수정되지 가진 이미지 256색 복사본을 사용하여 작업해야 합니다.

추가 정보

.gif 이미지 파일을 최대 256 색 표현할 수 있습니다. 색 부족한 리소스 .gif 파일 에서 때문에 이러한 색을 최적화 일반적으로 요청되는 작업입니다. 최적화된 색상표를 영향을 줄 수 임의의 사용자 지정 색 테이블 .gif 파일을 설정할 수 있어야 합니다.

GDI + 이미지 수정하고 GIF 인코더를 사용하여 이미지를 파일에 씁니다 후에는 GDI + 파일을 Image 개체를 비트 색 감소 않은 하프톤 색상표를 사용하여 씁니다. GDI + 에서 32 비트-픽셀별 (32 BPP) 색 변환을 수행하는 모든 수정 사항을 이미지 GDI + 32-BPP 그래픽 엔진 함께 이루어지기 때문에 때 이를 이미지 파일에 씁니다.

GDI + 이미지 및 다양한 픽셀 형식의 비트맵 은 생성을 지원하며, 따라서 .gif 이미지를 로드할 수 있지만 이들은 GDI + 에 의해 수정되는 경우 32-BPP 그래픽 엔진 사용을 32 BPP 변환이 필요하게. 그러나, 이미지 또는 비트맵 것으로 의해 수정되지 GDI + 원래 픽셀 형식으로 유지되며 함께 적절한 인코더 Save 메서드를 사용하여 파일에 쓸 수 있습니다. 이 속성은 이미지 사용자 지정 색 테이블이 .gif 파일로 저장할 수 있는 기술을 기초를 형성합니다.

수정되지 않은 비트맵 GIF 인코더가 작성하고 비트맵 색 테이블을 그대로 유지, 따라서 새 색상표를 .gif 파일을 저장하려면 이 메서드를 사용할 수 있습니다.

이 메서드는 이미지 데이터를 임시 비트맵 개체를 원래 이미지 개체를 복사하는 것입니다. 이 임시 비트맵 .gif 파일을 저장하는 데 사용되는 픽셀 형식을 수 있는 비트맵, 8-BPP 인덱싱할 때 만들어집니다. SetPalette 메서드를 사용하여 비트맵 색 테이블 설정되어 있고 위해 임시 비트맵 이미지를 정의를 복사한 다음. 임시 비트맵 중복된 정의를 만든 후 Save 메서드를 8-BPP 색 테이블 유지합니다 GIF 인코더 저장할 수 있습니다.

사용자 지정 색상표 가진 .gif 이미지를 작성하려면 다음과 같이 하십시오.
  1. 원본 이미지 같은 크기의 중복 비트맵 개체를 만듭니다.
  2. 비트맵 개체의 사용자 지정 색 테이블 원하는 색 테이블을 설정하십시오.
  3. LockBits 메서드를 복사본의 이미지 비트 쓰기 액세스할 수 있습니다.
  4. 이미지 정의에 원래 이미지 픽셀을 중복 LockBits 에서 가져온 메모리 색 인덱스를 작성하여 복사본을 만듭니다.
  5. UnLockBits를 이미지 비트를 해제할 수 있습니다.
  6. 비트맵 복사본을 사용하여 사용자 지정 색 테이블의 저장하고 GIF 인코더를 사용하여 이미지 파일로 저장할 수 있습니다.
  7. 이미지비트맵 복사본을 놓습니다.

샘플 코드 사용

이 문서의 예제 코드에서는 Bitmap.Save 임의의 크기의 사용자 지정 색상표 가진 .gif 파일을 작성하는 방법을 보여 줍니다. 데모를 위한 목적이 있으므로 코드 성능은 위해 최적화되어 있지 않습니다. 루프 처리 픽셀 최적화에 가장 좋은 기회가 있습니다. GetPixel 픽셀 형식의 편리한 추상화 있지만 매우 느립니다. 샘플 코드는 LockBits 픽셀 형식을 직접 액세스하는 데 사용되는 경우 훨씬 빠르게 됩니다. 속도를 높이려면 GetPixel 메서드 및 클래스 추상화 사용하지 마십시오. 성능을 향상시키려면 회색조로 변환을 부동 소수점 대신 정수 수학 사용하여 다시 작성하십시오.

예제 함수를 다음 다섯 개의 매개 변수를 사용합니다.
  • GDI + 이미지 개체입니다.
  • 대상 파일의 파일 이름입니다.
  • CLSID (클래스 식별자 () GIF 인코더.
  • 색 .gif 파일 수입니다.
  • 투명한 색이 필요한지 여부를 나타내는 플래그.
샘플 코드를 다운로드하려면 및 GDI + GetEncoderClsid 함수에 대한 자세한 내용은 다음 링크 시 MSDN 도움말 설명서를 참조하십시오.

플랫폼 SDK: GDI + - Image::Save (파일 이름, clsidEncoder, encoderParams)
http://msdn.microsoft.com/en-us/library/ms533843.aspx
이 함수는 먼저 비트맵 개체를 만듭니다 nColors 사용하여 .gif 파일을 만들려면 저장된 개체가 있기 때문에 PixelFormat8BPPIndexed 픽셀 형식을 가지며 다음 사용자 지정 색이 색상표에 만들어집니다. .gif 파일 크기 및 색 테이블에 대해 특정 항목에서 ColorPalette비트맵 개체 를 가져옵니다. 해당 알고리즘의 쉽게 통해 다양한 색 테이블 크기를 확장할 수 있기 때문에 회색조 이해 돕기 위한 샘플 코드를 만듭니다.

.gif 파일을 만들려면 다음 파일에 쓸 수 있는 이미지 정의와 함께 8-BPP 비트맵 개체를 초기화해야 합니다. 샘플 코드에서 중앙 루프를 데 사용되는 집합인 흑백 TV 색 공간 본질적으로 들어오는 이미지 색 변환.

데모 목적으로 원본 이미지의 픽셀 원본 이미지의 복사본을 비트맵 개체의 GetPixel 메서드는 통해 액세스할 수 있습니다. 이미지 클래스 GetPixel 메서드를 구현하지 않으므로 비트맵 복사본을 이루어집니다.

다른 기술을 사용하여 직접 액세스할 수 LockBits 메서드 또는 interop Windows GDI DIB 섹션 함께 사용하여 픽셀 픽셀 액세스할 수 있습니다. 비트맵을 Gdi + HDC에서 GDI DIB 구역 메모리 도메인 컨트롤러로 복사하려면 BitBlt 함수를 사용하면 GDI 색 일치 능력을 GBitBlt 함수를 사용합니다.

비트맵 복사본을 만든 후에는 비트맵의 대상 파일에 쓸 수 제공된 GIF CLSID Save 메서드를 사용하십시오.

256색 미만의 GIF 파일

GIF 코덱이 GDI + 버전 1.0의 8 BPP 있는 경우에만 GDI + 이미지 인코딩합니다. 인코딩 전에 다른 모든 이미지 형식으로 변환됩니다. 이 코드는 GIF 코덱을 256색 미만의 ColorPalette.Count 이 속성이 포함된 8-BPP 비트맵 개체의 인식하므로 256색 미만의 .gif 파일을 쓸 8-BPP 비트맵 형식을 사용합니다.

GIF 코덱 픽셀 형식에 대한 자세한 내용은 이 문서의 "References" 절을 참조하십시오.

코드를 한 픽셀 인덱스 값을 계산하는 경우 위해 8-BPP 비트맵 이미지의 픽셀 정의를 복사하는 처리 루프 코드에서 색상표의 크기를 고려합니다. GIF 코덱을 색상표의 크기를 제한하는 및 이미지 정의 색상표 크기 (즉, 잠재적인 GIF 색 테이블), 호환 가능하며 따라서 미만의 256색을 .gif 파일을 만들 수 있습니다 인덱스 값으로 제한합니다.

GIF 투명도

샘플 코드에서 ColorPalette 작성 루틴에서 투명도 기능의 사용을 보여 주기 위해 GIF 투명한 색을 수 첫 번째 항목을 설정합니다. 코드 항목의 알파 구성 요소가 0으로 설정하여지 않습니다. 이 문서의 예제 코드는 데모를 위한 용도로만, 따라서 투명색을 임의의 선택할 수 있으며 있을 수 있습니다 원본 이미지 전적으로 의존하는 예기치 않은 결과가.

GIF 인코더 알파 값이 0 이면 투명한 색으로 ColorPalette 첫 번째 색을 식별합니다. 즉, 투명한 색 ColorPalette 첫 번째 항목은 필요가 없습니다. preceeding 항목을 모두 0이 아닌 값으로 알파 구성 요소를 포함하는 시 있는 조건을 것을 색상표에서 가능한 256 색 중 하나를 수 있습니다. 알파 구성 요소 값이 0 나중에 항목이 무시됩니다. 0이 아닌 알파 구성 요소가 모든 항목은 불투명 간주됩니다.

참고: 이 코드를 사용하면 기존 파일을 덮어쓸 때 결과 파일의 크기가 문제가 발생할 수 있습니다. GDI + 버전 1.0 파일을 잘라낼 버그로 인해 발생합니다.

이미지 파일 크기에 대한 자세한 내용은 이 문서의 "References" 절을 참조하십시오. 방법이 참조한 문서 System.Drawing 네임스페이스의 비트맵 클래스는 .NET Framework의 사용에 대해 설명합니다. 있지만 System.Drawing GDI + 를 통해 구현되므로 항목을 GDI + 적용됩니다.

GIF/LZW 발급 라이선스

Microsoft은 .gif 파일 형식과 Unisys 소유한 미국 및 Microsoft 제품 수 외래 특허권 다루는 다른 LZW 기술을 사용하도록 Unisys 라이센스를 얻은 있습니다. 그러나 이 라이센스 Microsoft 개발 제품 또는 도구 키트 응용 프로그램을 개발하는 데 사용하는 타사 개발자에게 확장되지 않습니다. 타사 개발자는 GIF 형식 또는 LZW 기술을 사용하도록 Unisys에서 라이센스를 얻어야 합니다 여부를 결정해야 합니다.

LZW 라이센스 및 GIF에 대한 자세한 내용은 아래 문서 번호를 눌러 Microsoft 기술 자료에 있는 문서를 클릭하십시오.
193543정보: Unisys GIF 및 LZW 기술 라이센스 정보

예제 코드

Status SaveGIFWithNewColorTable(
  Image *pImage,
  const WCHAR* filename,
  const CLSID* clsidEncoder,
  DWORD nColors,
  BOOL fTransparent
)
{
    Status stat = GenericError;

    // GIF codec supports 256 colors maximum.
    if (nColors > 256)
        nColors = 256;
    if (nColors < 2)
        nColors = 2;

    // Make a new 8-BPP pixel indexed bitmap that is the same size as the source image.
    DWORD   dwWidth = pImage->GetWidth();
    DWORD   dwHeight = pImage->GetHeight();

    // Always use PixelFormat8BPPIndexed, because that is the color table
    // based interface to the GIF codec.
    Bitmap  bitmap(dwWidth, dwHeight, PixelFormat8BppIndexed); 

    stat = bitmap.GetLastStatus();

    if (stat != Ok)
        return stat;        // No point in continuing.

    // Allocate the new color table.
    DWORD   dwSizeColorPalette;
    dwSizeColorPalette = sizeof(ColorPalette);      // Size of core structure.
    dwSizeColorPalette += sizeof(ARGB)*(nColors-1);   // The other entries.

    // Allocate some raw space to back the ColorPalette structure pointer.
    ColorPalette *ppal = (ColorPalette *)new BYTE[dwSizeColorPalette];
    if (ppal == NULL) return OutOfMemory;

    ZeroMemory(ppal, dwSizeColorPalette);

    // Initialize a new color table with entries that are determined by
    // some optimal palette finding algorithm; for demonstration 
    // purposes, just do a grayscale. 
    if (fTransparent)
        ppal->Flags = PaletteFlagsHasAlpha;
    else
        ppal->Flags = 0; 
    ppal->Flags |= PaletteFlagsGrayScale;
    ppal->Count = nColors;
    for (UINT i = 0; i < nColors; i++)
    {
        int Alpha = 0xFF;       // Colors are opaque by default.
        int Intensity = i*0xFF/(nColors-1); // even distribution 

        // The GIF encoder makes the first entry in the palette with a
        // zero alpha the "transparent" color in the GIF.
        // For demonstration purposes, the first one is picked arbitrarily.

        if ( i == 0 && fTransparent) // Make this color index...
            Alpha = 0;          // Transparent
        
        // Create a gray scale for demonstration purposes.
        // Otherwise, use your favorite color reduction algorithm
        // and an optimum palette for that algorithm generated here.
        // For example, a color histogram, or a median cut palette.
        ppal->Entries[i] = Color::MakeARGB( Alpha, 
                                            Intensity, 
                                            Intensity, 
                                            Intensity );
    }

    // Set the palette into the new Bitmap object.
    bitmap.SetPalette(ppal);


    // Use GetPixel below to pull out the color data of Image.
    // Because GetPixel isn't defined on an Image, make a copy in a Bitmap 
    // instead. Make a new Bitmap that is the same size of the image that
    // you want to export. Otherwise, you might try to interpret the native 
    // pixel format of the image by using a LockBits call.
    // Use PixelFormat32BppARGB so that you can wrap a Graphics around it.
    Bitmap BmpCopy(dwWidth, dwHeight, PixelFormat32BppARGB); 
    stat = BmpCopy.GetLastStatus();
    if (stat == Ok)
    {
        Graphics g(&BmpCopy);

        // Transfer the Image to the Bitmap.
        stat = g.DrawImage(pImage, 0, 0, dwWidth, dwHeight);

        // g goes out of scope here and cleans up.
    }

    if (stat != Ok)
    {
        delete [] (LPBYTE) ppal;
        ppal = NULL;
        return stat;
    }

    // Lock the whole of the bitmap for writing.
    BitmapData  bitmapData;
    Rect        rect(0, 0, dwWidth, dwHeight);

    stat = bitmap.LockBits(
      &rect,
      ImageLockModeWrite,
      PixelFormat8BppIndexed,
      &bitmapData);

    if (stat == Ok)
    {
        // Write to the temporary buffer provided by LockBits.
        // Copy the pixels from the source image in this loop.
        // Because you want an index, convert RGB to the appropriate
        // palette index here.
        BYTE *pixels;
        if (bitmapData.Stride > 0)
            pixels = (BYTE*) bitmapData.Scan0;
        else
            // If the Stride is negative, Scan0 points to the last             // scanline in the buffer.
            // To normalize the loop, obtain the start of the buffer,
            // which is located (Height-1) scanlines previous.
            pixels = (BYTE*) bitmapData.Scan0 + bitmapData.Stride*(dwHeight-1);
        UINT stride = abs(bitmapData.Stride);

        // Top-down and bottom-up is not relevant to this algorithm.

        for(UINT row = 0; row < dwHeight; ++row)
        {
          for(UINT col = 0; col < dwWidth; ++col)
          {
              // Map palette indexes for a grayscale.
              // If you use some other technique to color convert,
              // put your favorite color reduction algorithm here.
              Color     pixel;
              UINT      i8BppPixel = row * stride + col;

              BmpCopy.GetPixel(col, row, &pixel);

              // Use luminance/chrominance conversion to get grayscale.
              // Basically, turn the image into black and white TV: YCrCb.
              // You do not have to to calculate Cr or Cb because you 
              // throw away the color anyway.
              // Y = Red * 0.299 + Green * 0.587 + Blue * 0.114

              // This expression is best as integer math for performance,
              // however, because GetPixel listed earlier is the slowest 
              // part of this loop, the expression is left as 
              // floating point for clarity.
              double luminance = (pixel.GetRed() * 0.299) +
                                (pixel.GetGreen() * 0.587) +
                                (pixel.GetBlue() * 0.114);

              // Gray scale is an intensity map from black to white.
              // Compute the index to the gray scale entry that  
              // approximates the luminance, and then round the index.      
              // Also, constrain the index choices by the number of colors to do
              pixels[i8BppPixel] = (BYTE)(luminance * (nColors-1)/255 +0.5);
          }
        }
    // To commit the changes, unlock the portion of the bitmap.  
        stat = bitmap.UnlockBits(&bitmapData);
    }

    // If destination work was successful, see whether the source was successful.
    if (stat == Ok) stat = BmpCopy.GetLastStatus();

    // See whether the code has been successful to this point.
    if (stat == Ok)
    {
    // Write it out to the disk.
        stat =  bitmap.Save(filename, clsidEncoder, NULL);
    }

    // Clean up after yourself.
    delete [] (LPBYTE) ppal;
    ppal = NULL;
    // BmpCopy goes away on its own when it falls out of scope.

    return stat;
}
				

대한 예제 코드

Microsoft을 배제하며 제한되지 않은 묵시적된 보증 (상품성 및 특정 목적에의 적합성에 대한 묵시적인, 목적으로만 프로그래밍 예제를 제공합니다. 이 문서에서는 프로시저를 작성하고 디버깅하는 데 사용되는 도구 및 여기서 설명하는 프로그래밍 언어에 익숙한 사용자를 대상으로 합니다. Microsoft 기술 지원 담당자는 특정 절차에 대한 기능을 설명할 수 있지만 추가 기능을 제공하거나 특정 요구 사항에 맞도록 프로시저를 구성하지는 이 예제를 수정하지 않습니다.
프로그래밍 경험이 제한되어 있으면 Microsoft 인증 파트너 문의하거나 Microsoft 자문 서비스 할 수 있습니다. 자세한 내용은 다음 Microsoft 웹 사이트를 방문하십시오.

Microsoft 파트너 - https://partner.microsoft.com/global/30000104 인증

Microsoft 권고 서비스 - http://support.microsoft.com/gp/advisoryservice

사용할 수 있는 지원 옵션 및 Microsoft 연락하는 방법에 대한 자세한 내용은 다음 Microsoft 웹 사이트를 방문하십시오: http://support.microsoft.com/default.aspx?scid=fh;EN-US;CNTACTMS

참조

GIF 코덱 픽셀 형식에 대한 자세한 내용은 아래 문서 번호를 눌러 Microsoft 기술 자료에 있는 문서를 클릭하십시오.
318343정보: 8-BPP 서식 사용 GDI + GIF 파일 저장.
이미지 파일 크기에 대한 자세한 내용은 아래 문서 번호를 눌러 Microsoft 기술 자료에 있는 문서를 클릭하십시오.
312119PRB: 파일 크기 비트맵 클래스의 Save 메서드 검사점에서 있지 않음
이 링크를 참조하는 문서에서는 .NET Framework System.Drawing 네임스페이스의 Bitmap 클래스 사용에 대해 설명합니다. 있지만 System.Drawing GDI + 를 통해 구현되므로 항목을 GDI + 적용됩니다.

용어집

BPP
비트/픽셀 - 비트 수 디지털화된 이미지에서 각 픽셀의 색 값을 나타내는 데 사용되는; 이미지의 각 픽셀 색 정의의 실제 레이아웃에 대해 설명합니다. 일반 및 일반적으로 참조된 픽셀 형식은 32 BPP, 24 BPP, BPP 16, 8 BPP, BPP 4, 1 BPP이 포함됩니다.
8 BPP
한 바이트가 포함된 8비트가 표현됩니다 이미지의 픽셀 형식. 바이트 값은 실제 빨강-녹색-파랑 RGB 색 정의를 포함하는 색 테이블에 대한 인덱스로 사용됩니다. 색상표에 인덱스를 한 바이트 크기 에서 때문에 256색으로 제한됩니다.
GIF
그래픽 교환 형식 - CompuServe에 의해 만들어진 streamable 이미지 파일 형식입니다.
RGB
빨강, 녹색 및 파랑 - 각 일반적으로, 바이트로 표현되는 및 세 개로 있는 색 3 바이트 구분에서 결과.

속성

기술 자료: 315780 - 마지막 검토: 2007년 2월 12일 월요일 - 수정: 3.5
본 문서의 정보는 다음의 제품에 적용됩니다.
  • Microsoft GDI+ 1.0
  • Microsoft Windows XP Professional
  • the operating system: Microsoft Windows XP 64-Bit Edition
키워드:?
kbmt kbdswgdi2003swept kbbitmap kbgdiplus kbhowto KB315780 KbMtko
기계 번역된 문서
중요: 본 문서는 전문 번역가가 번역한 것이 아니라 Microsoft 기계 번역 소프트웨어로 번역한 것입니다. Microsoft는 번역가가 번역한 문서 및 기계 번역된 문서를 모두 제공하므로 Microsoft 기술 자료에 있는 모든 문서를 한글로 접할 수 있습니다. 그러나 기계 번역 문서가 항상 완벽한 것은 아닙니다. 따라서 기계 번역 문서에는 마치 외국인이 한국어로 말할 때 실수를 하는 것처럼 어휘, 구문 또는 문법에 오류가 있을 수 있습니다. Microsoft는 내용상의 오역 또는 Microsoft 고객이 이러한 오역을 사용함으로써 발생하는 부 정확성, 오류 또는 손해에 대해 책임을 지지 않습니다. Microsoft는 이러한 문제를 해결하기 위해 기계 번역 소프트웨어를 자주 업데이트하고 있습니다.

피드백 보내기

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com