JPEG 影像的不失真轉換
當您壓縮 JPEG 映射時,影像中的某些資訊會遺失。 如果您開啟 JPEG 檔案、改變映射,並將它儲存到另一個 JPEG 檔案,品質將會降低。 如果您重複該程式多次,您會看到影像品質大幅降低。
因為 JPEG 是網路上最熱門的影像格式之一,而且因為人們經常想要修改 JPEG 影像,所以 GDI+ 提供下列轉換,可在 JPEG 映射上執行,而不會遺失資訊:
- 旋轉 90 度
- 旋轉 180 度
- 旋轉 270 度
- 水準翻轉
- 垂直翻轉
呼叫Image物件的Save方法時,您可以套用上述清單中顯示的其中一個轉換。 如果符合下列條件,轉換將會繼續,而不會遺失資訊:
- 用來建構 Image 物件的檔案是 JPEG 檔案。
- 影像的寬度和高度都是 16 的倍數。
如果影像的寬度和高度不是 16 倍的倍數,GDI+ 將會在您套用上述清單中的其中一個旋轉或翻轉轉換時,最好保留影像品質。
若要轉換 JPEG 影像,請初始化EncoderParameters物件,並將該物件的位址傳遞至Image類別的Save方法。 初始化 EncoderParameters 物件,使其具有包含一個 EncoderParameter 物件的陣列。 初始化該一個EncoderParameter物件,使其Value成員指向保留EncoderValue列舉之下列其中一個元素的ULONG變數:
- EncoderValueTransformRotate90,
- EncoderValueTransformRotate180,
- EncoderValueTransformRotate270,
- EncoderValueTransformFlipHorizontal,
- EncoderValueTransformFlipVertical
將EncoderParameter物件的Guid成員設定為 EncoderTransformation。
下列主控台應用程式會從 JPEG 檔案建立 Image 物件,然後將映射儲存至新的檔案。 在儲存過程中,影像會旋轉 90 度。 如果影像的寬度和高度都是 16 的倍數,則旋轉和儲存影像的程式不會遺失資訊。
主要函式依賴協助程式函式 GetEncoderClsid,其顯示在 擷取編碼器的類別識別碼中。
#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;
INT GetEncoderClsid(const WCHAR* format, CLSID* pClsid); // helper function
INT main()
{
// Initialize GDI+.
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
CLSID encoderClsid;
EncoderParameters encoderParameters;
ULONG transformation;
UINT width;
UINT height;
Status stat;
// Get a JPEG image from the disk.
Image* image = new Image(L"Shapes.jpg");
// Determine whether the width and height of the image
// are multiples of 16.
width = image->GetWidth();
height = image->GetHeight();
printf("The width of the image is %u", width);
if(width / 16.0 - width / 16 == 0)
printf(", which is a multiple of 16.\n");
else
printf(", which is not a multiple of 16.\n");
printf("The height of the image is %u", height);
if(height / 16.0 - height / 16 == 0)
printf(", which is a multiple of 16.\n");
else
printf(", which is not a multiple of 16.\n");
// Get the CLSID of the JPEG encoder.
GetEncoderClsid(L"image/jpeg", &encoderClsid);
// Before we call Image::Save, we must initialize an
// EncoderParameters object. The EncoderParameters object
// has an array of EncoderParameter objects. In this
// case, there is only one EncoderParameter object in the array.
// The one EncoderParameter object has an array of values.
// In this case, there is only one value (of type ULONG)
// in the array. We will set that value to EncoderValueTransformRotate90.
encoderParameters.Count = 1;
encoderParameters.Parameter[0].Guid = EncoderTransformation;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;
// Rotate and save the image.
transformation = EncoderValueTransformRotate90;
encoderParameters.Parameter[0].Value = &transformation;
stat = image->Save(L"ShapesR90.jpg", &encoderClsid, &encoderParameters);
if(stat == Ok)
wprintf(L"%s saved successfully.\n", L"ShapesR90.jpg");
else
wprintf(L"%d Attempt to save %s failed.\n", stat, L"ShapesR90.jpg");
delete image;
GdiplusShutdown(gdiplusToken);
return 0;
}
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應