Transformasi lossless dari gambar JPEG

Saat Anda memadatkan gambar JPEG, beberapa informasi dalam gambar hilang. Jika Anda membuka file JPEG, mengubah gambar, dan menyimpannya ke file JPEG lain, kualitasnya akan berkurang. Jika Anda mengulangi proses itu berkali-kali, Anda akan melihat degradasi substansial dalam kualitas gambar.

Karena JPEG adalah salah satu format gambar paling populer di Web, dan karena orang sering suka memodifikasi gambar JPEG, GDI+ menyediakan transformasi berikut yang dapat dilakukan pada gambar JPEG tanpa kehilangan informasi:

  • Putar 90 derajat
  • Putar 180 derajat
  • Putar 270 derajat
  • Balikkan secara horizontal
  • Balikkan secara vertikal

Anda dapat menerapkan salah satu transformasi yang ditampilkan dalam daftar sebelumnya saat Anda memanggil metode Simpan objek Gambar . Jika kondisi berikut terpenuhi, transformasi akan dilanjutkan tanpa kehilangan informasi:

  • File yang digunakan untuk membuat objek Gambar adalah file JPEG.
  • Lebar dan tinggi gambar keduanya adalah kelipatan 16.

Jika lebar dan tinggi gambar tidak keduanya kelipatan 16, GDI+ akan melakukan yang terbaik untuk mempertahankan kualitas gambar saat Anda menerapkan salah satu transformasi rotasi atau membalik yang ditunjukkan dalam daftar sebelumnya.

Untuk mengubah gambar JPEG, inisialisasi objek EncoderParameters dan teruskan alamat objek tersebut ke metode Simpan dari kelas Gambar . Inisialisasi objek EncoderParameters sehingga memiliki array yang terdiri dari satu objek EncoderParameter . Inisialisasi bahwa satu objek EncoderParameter sehingga anggota Nilainya menunjuk ke variabel ULONG yang menyimpan salah satu elemen enumerasi EncoderValue berikut:

  • EncoderValueTransformRotate90,
  • EncoderValueTransformRotate180,
  • EncoderValueTransformRotate270,
  • EncoderValueTransformFlipHorizontal,
  • EncoderValueTransformFlipVertical

Atur anggota Guid objek EncoderParameter ke EncoderTransformation.

Aplikasi konsol berikut membuat objek Gambar dari file JPEG lalu menyimpan gambar ke file baru. Selama proses penyimpanan, gambar diputar 90 derajat. Jika lebar dan tinggi gambar keduanya kelipatan 16, proses memutar dan menyimpan gambar tidak menyebabkan hilangnya informasi.

Fungsi utama bergantung pada fungsi pembantu GetEncoderClsid, yang ditunjukkan dalam Mengambil Pengidentifikasi Kelas untuk Encoder.

#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;
}