이 질문에서는 GDI에서 지원하는 대부분의 이미지 파일 형식과 GDI에서 이미지 파일 처리를 위해 제공하는 두 가지 클래스인 Image와 Bitmap에 대해 소개합니다. 이미지 파일의 형식과 데이터 저장 구조가 서로 다른 형식으로 변환됩니다. 이미지 파일의 표시는 파일 데이터 구조를 분석한 후 관련 이미지 데이터를 읽어서 수행됩니다. 이제 GDI는 이미지를 쉽게 처리할 수 있도록 Image 및 Bitmap 클래스를 제공합니다.
개요
GDI는 BMP, GIF, JPEG, TIFF 및 PNG와 같은 가장 널리 사용되는 이미지 파일 형식을 지원합니다. 먼저 이러한 이미지 파일을 소개한 다음 Image 및 Bitmap 클래스에서 지원하는 기능을 설명하겠습니다.
1. 이미지 파일 형식 소개
이미지 파일은 이미지를 묘사하는 컴퓨터 디스크 파일로, 파일 형식은 수십 가지가 넘습니다. 여기서는 BMP, GIF, JPEG, TIFF 및 PNG와 같은 이미지 파일 형식만 소개합니다.
BMP 파일 형식
BMP 이미지 파일 형식은 Microsoft에서 Windows 환경을 위해 설정한 표준 이미지 형식입니다. Windows BMP 비트맵은 실제로 디스플레이 픽셀에 해당하는 일부 비트 배열입니다. 하나는 GDI 비트맵이고 다른 하나는 DIB 비트맵(Device-Independent Bitmap)입니다. GDI 비트맵에는 Windows의 GDI 모듈과 관련된 Windows 데이터 구조가 포함되어 있습니다. 이 데이터 구조는 장치와 관련되어 있으므로 이 비트맵을 DDB 비트맵(Device-Dependent Bitmap)이라고도 합니다. 사용자 프로그램이 비트맵 데이터 정보를 얻을 때 비트맵 표시 방법은 디스플레이 카드에 따라 다릅니다. GDI 비트맵의 이러한 장치 종속성으로 인해 비트맵이 네트워크를 통해 다른 PC로 전송될 때 문제가 발생할 수 있습니다.
DIB는 자체 색상 정보 등 GDI 비트맵에 비해 많은 프로그래밍 이점을 제공하므로 팔레트 관리가 더 쉬워집니다. Windows를 실행하는 모든 컴퓨터는 DIB를 처리할 수 있으며 일반적으로 DIB는 확장명이 .BMP인 파일로 디스크에 저장되거나 프로그램의 EXE 또는 DLL 파일에 리소스로 존재합니다.
GIF 파일 형식
그래픽 교환 형식(GIF--Graphics Interchange Format)은 1987년 6월 15일 CompuServe에 의해 처음 확립되었습니다. 주로 CompuServe 네트워크 그래픽 데이터에 사용됩니다. 전송 및 저장. GIF는 다양한 입출력 장치가 쉽게 이미지를 교환할 수 있도록 충분한 정보를 제공하고 이 정보를 잘 구성합니다. 24비트 색상을 지원하며 최대 256가지 색상의 팔레트로 구현되며 최대 이미지 크기는 64K x입니다. 64K 픽셀. GIF에는 LZW 압축, 다중 이미지 및 인터레이스 화면 그리기 기능이 있습니다.
JPEG 파일 형식
국제 표준화 기구(ISO)와 국제 전신 자문위원회가 공동으로 설립한 "공동 사진 전문가 그룹" JPEG(공동 사진 전문가 그룹) Telephone(CCITT)은 수년간의 힘들고 세심한 작업 끝에 1991년 3월에 "다중 회색조 정지 이미지의 디지털 압축 코딩"(흔히 JPEG 표준이라고도 함)이라는 권장 사항 초안 ISO CD 10918이 제안되었습니다. 이는 컬러 및 흑백 다중 회색조 또는 연속 톤 정지 디지털 이미지에 대한 압축 표준입니다. 여기에는 이산 코사인 변환 및 허프만 코딩을 기반으로 하는 무손실 압축과 손실 압축의 두 부분이 포함됩니다. 전자는 왜곡을 생성하지 않지만 압축률은 매우 작습니다. 후자의 알고리즘이 이미지 압축을 수행할 때 정보가 손실되더라도 압축률은 매우 클 수 있습니다.
예를 들어 20~40배로 압축하면 왜곡은 기본적으로 사람의 눈에 보이지 않습니다.
JPEG 이미지 파일도 픽셀 형식의 파일 형식이지만 BMP와 같은 이미지 파일보다 훨씬 복잡합니다. 다행스럽게도 GDI의 이미지는 JPEG 파일 형식을 지원하므로 JPEG 형식에 대해 많이 알지 않고도 이 형식의 이미지를 처리할 수 있습니다.
TIFF 파일 형식
TIFF(Tagged Image Format File, 로고 이미지 파일 형식)는 1986년 Aldus Company에서 처음 출시되었습니다. 흑백에서 24비트 트루 컬러까지 모든 것을 처리할 수 있습니다. . 모든 이미지가 잘 지원되며 다양한 플랫폼 간에 쉽게 수정하고 변환할 수 있습니다. 다른 이미지 파일 형식과 달리 TIFF 파일에는 파일에 저장된 이미지 데이터 유형, 색상 및 압축 방법을 정의하는 데 사용되는 태그 정보 영역이 있습니다.
PNG 파일 형식
PNG(Portable Network Graphic, 휴대용 네트워크 이미지) 파일 형식은 Thomas Boutell, Tom Lane 등이 제안하고 설계한 것으로 네트워크에 적응하기 위한 것입니다. 데이터 전송용으로 설계된 이미지 파일 형식으로, GIF 이미지 파일 형식을 보다 간단한 형식과 엄격한 특허 제한으로 대체합니다. 게다가 이 이미지 파일 형식은 더 복잡한 TIFF 이미지 파일 형식을 어느 정도 대체할 수도 있습니다. 주요 기능은 다음과 같습니다. 압축 효율성은 일반적으로 GIF보다 높으며, 이미지의 투명도를 제어하는 알파 채널을 제공하고, 이미지의 밝기를 조정하는 감마 보정 메커니즘을 지원합니다.
PNG 파일 형식은 트루 컬러 이미지, 회색조 이미지, 색상 인덱스 데이터 이미지의 세 가지 주요 이미지 유형을 지원합니다. JPEG는 처음 두 가지 이미지 유형만 지원하며 GIF는 회색조 팔레트를 사용하여 이미지의 회색조 수준을 보정할 수 있지만 원칙적으로 세 번째 이미지 유형만 지원합니다.
마법사 및 비트맵 클래스 개요
GDI의 Image 클래스는 BMP, GIF, JPEG, PNG, TIFF, WMF(Windows Metafile) 및 EMF(Enhanced WMF) 이미지 파일을 캡슐화합니다. 형식 변환 및 간단한 처리 기능. 비트맵은 Windows 비트맵 작업의 일반적인 기능을 캡슐화하는 Image 클래스에서 상속된 이미지 클래스입니다. 예를 들어, Bitmap::SetPixel 및 Bitmap::GetPixel은 각각 비트맵에서 픽셀 작업을 읽고 쓰는 데 사용되며, 이는 이미지를 부드럽게 하고 선명하게 할 수 있는 가능성을 제공할 수 있습니다.
3. DrawImage 메소드
DrawImage는 이미지를 표시하기 위한 GDI Graphics 클래스의 핵심 메소드이며 오버로드된 기능이 많이 있습니다. 일반적으로 사용되는 일반 오버로드 함수는 다음과 같습니다:
Status DrawImage(Image* image, INT x, INT y)
Status DrawImage(Image* image, const Rectamp; ret); p>
상태 DrawImage( 이미지* 이미지, const Point* destPoints, INT count)
상태 DrawImage( 이미지* 이미지, INT x, INT y, INT srcx, INT srcy,
상태 DrawImage( 이미지* 이미지, INT x, INT y, INT srcx, INT srcy,
p>
INT srcwidth, INT srcheight, Unit srcUnit); p> 그 중 (x, y)는 이미지가 표시되는 위치를 지정하는데 사용되는데, 이는 이미지의 왼쪽 상단에 해당합니다.
ect는 이미지가 채우는 직사각형 영역을 지정하는 데 사용되며, destPoints와 count는 각각 다각형의 꼭지점과 꼭지점 수를 지정하는 데 사용됩니다. 개수가 3이면 다각형이 평행사변형이고 다른 꼭지점은 시스템에 의해 자동으로 지정된다는 의미입니다. 이때, destPoints의 데이터는 원본 이미지의 왼쪽 상단, 오른쪽 상단, 왼쪽 하단의 정점 좌표에 해당합니다. srcx, srcy, srcwidth 및 srcheight는 표시할 소스 이미지의 위치와 크기를 지정하는 데 사용됩니다. srcUnit은 사용되는 단위를 지정하는 데 사용되며 기본적으로 픽셀을 측정 단위로 사용합니다.
이미지 파일 호출 및 표시
GDI에서 이미지 파일을 호출하고 표시하는 것은 일반적으로 먼저 Image 또는 Bitmap을 통해 이미지 파일을 호출하여 객체를 구성하고, 그런 다음 Graphics ::DrawImage 메서드를 호출하면 지정된 위치에 이미지 전체 또는 일부가 표시됩니다. 예를 들어 다음 코드는 다음과 같습니다.
void CEx_GDIPlusView::OnDraw(CDC* pDC)
{
CEx_GDIPlusDoc* pDoc = GetDocument()
ASSERT_VALID(pDoc);
네임스페이스 Gdiplus 사용
그래픽 그래픽( pDC-gt; m_hDC)
이미지(L"sunflower) .jpg ");
graphic.DrawImage(amp; image, 10, 10);
Rect ect(130, 10, image.GetWidth(), image.GetHeight() );
graphic.DrawImage(amp; image, ret);
}
그림 7.17에서 결과를 볼 수 있습니다. 두 번 DrawImage의 결과가 다르며 동일해야 합니다. 무슨 일이 일어나고 있는 걸까요? 표시 영역 크기를 지정하지 않으면 DrawImage가 장치 해상도에 따라 자동으로 크기가 조정되어 표시 결과가 달라지는 것으로 나타났습니다.
물론 Bitmap 클래스를 사용하여 이미지 파일을 로드하여 Bitmap 객체를 구성할 수도 있으며 결과는 동일합니다. 예를 들어, 위의 코드는 다음과 같이 변경할 수 있습니다:
Bitmap bmp(L"sunflower.jpg")
graphics.DrawImage(amp; bmp, 10, 10); /p>
Rect(130, 10, bmp.GetWidth(), bmp.GetHeight())
graphics.DrawImage(amp; bmp, ret); > 설명 필요 또한 Image는 DrawImage를 호출한 후 썸네일 포인터를 얻기 위한 GetThumbnailImage 메서드도 제공하는데, 이는 이미지를 미리 볼 때 매우 유용합니다.
예를 들어, 다음 코드는:
그래픽 그래픽( pDC-gt; m_hDC )
이미지 이미지(L"sunflower.jpg")
이미지 * pThumbnail = image.GetThumbnailImage(50, 50, NULL, NULL)
//썸네일 표시
graphics.DrawImage(pThumbnail, 20, 20); p >//사용 후에는 썸네일 포인터를 삭제하는 것을 잊지 마세요.
delete pThumbnail;
이미지 회전 및 늘이기
일반적으로 이미지 회전 및 늘이기 이는 DrawImage에서 destPoints 매개변수를 지정하여 달성됩니다. destPoints에는 새 좌표계에 대해 정의된 점의 데이터가 포함됩니다. 그림 7.18은 좌표계 정의 방법을 보여줍니다.
그림에서 알 수 있듯이 destPoints의 첫 번째 점은 좌표의 원점을 정의하는 데 사용되며 두 번째 점은 X축의 방법과 X 방향의 크기를 정의하는 데 사용됩니다. 세 번째 포인트는 Y축과 이미지의 Y방향 크기를 정의하는 데 사용되는 방법입니다. destPoints에 의해 정의된 새 좌표계의 두 축이 수직이 아닌 경우 이미지 스트레칭 효과를 얻을 수 있습니다.
다음 코드는 이미지 회전 및 늘이기의 예이며, 그 결과는 그림 7.19와 같습니다.
이미지 이미지(L"sunflower.jpg")
graphics.DrawImage(amp; image, 10, 10)
포인트 포인트[] = { Point(0, 0), Point(image.GetWidth(), 0),
Point(0, image.GetHeight())}
행렬 행렬(1, 0, 0, 1, 230, 10); // 단위 행렬을 정의합니다. 좌표의 원점은 (230, 10)입니다.
matrix.Rotate(30) // 시계 방향으로 30도 회전합니다. /p >
matrix.Scale(0.63, 0.6); // X 및 Y 방향에 각각 0.63 및 0.6 배율 인수를 곱합니다.
matrix.TransformPoints(points, 3) // 사용 점을 변환하는 이 행렬
graphics.DrawImage(amp; image, points, 3)
Point newpoints[] = {Point(450, 10), Point(510, 60) ), Point(350 , 80)};
graphics.DrawImage(amp; image, newpoints, 3)
물론 Graphics::RotateTransform을 직접 사용할 수도 있습니다. 다음 코드와 같은 이미지 회전. 그러나 이렇게 설정하면 앞으로의 모든 그리기 결과가 회전되므로 때로는 불편할 수 있습니다.
Image image(L"sunflower.jpg");
graphics.TranslateTransform(230, 10); // 원점을 (230, 10)으로 이동합니다.
graphics.RotateTransform(30); // 시계 방향으로 30도 회전
graphics.DrawImage(amp; image, 0, 0)
보간 알고리즘의 품질 조정
이미지 크기를 조정할 때 이미지 픽셀을 보간해야 합니다. 보간 알고리즘에 따라 효과도 달라집니다. 그래픽:: SetInterpolationMode를 사용하면 필요에 따라 다양한 품질 효과를 갖는 보간 알고리즘을 사용할 수 있습니다. 물론 품질이 높을수록 렌더링하는 데 시간이 더 오래 걸립니다. 다음 코드는 다양한 품질 효과를 사용한 보간 알고리즘 모드이며 그 결과는 그림 7.20에 나와 있습니다. 그래픽 그래픽( pDC-gt; m_hDC );
이미지 이미지(L"log.gif")
UINT width = image.GetWidth(); >UINT height = image.GetHeight();
// 크기 조정 없음
graphics.DrawImage(amp; image, 10, 10)/ / 저품질 보간 알고리즘 사용
graphics.SetInterpolationMode(InterpolationModeNearestNeighbor)
graphics.DrawImage( amp; image,
Rect(170, 30, (INT )(0.6*width), (INT)(0.6*height)));
// 중간 품질 보간 알고리즘 사용
graphics.SetInterpolationMode(InterpolationModeHighQualityBilinear)
graphics.DrawImage( amp; 이미지,
Rect(270, 30, (INT)(0.6*너비), (INT)(0.6*높이)))
p>
// 고품질 보간 알고리즘 사용
graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic)
graphics.DrawImage( amp; image,
Rect(370, 30, (INT)(0.6*width), (INT)(0.6*height)))
사실 Image에는 이보다 더 많은 기능이 있습니다. 예를 들어 차이점도 있습니다. 서로 다른 형식의 파일 간 변환 등 그러나 이러한 기능은 기본적으로 MFC의 새로운 CImage 클래스와 동일하지만 CImage는 MFC 프로그래머의 프로그래밍 습관과 더 일치하므로 다음 섹션에서는 CImage의 사용법과 기술에 중점을 둘 것입니다.