Partilhar via


Transformação sem perdas de uma imagem JPEG

Quando você compacta uma imagem JPEG, algumas das informações na imagem são perdidas. Se você abrir um arquivo JPEG, alterar a imagem e salvá-la em outro arquivo JPEG, a qualidade diminuirá. Se você repetir esse processo muitas vezes, verá uma degradação substancial na qualidade da imagem.

Como JPEG é um dos formatos de imagem mais populares na Web e, como as pessoas geralmente gostam de modificar imagens JPEG, o GDI+ fornece as seguintes transformações que podem ser executadas em imagens JPEG sem perda de informações:

  • Girar 90 graus
  • Girar 180 graus
  • Girar 270 graus
  • Inverter horizontalmente
  • Inverter verticalmente

Você pode aplicar uma das transformações mostradas na lista anterior ao chamar o método Salvar de um objetoimage. Se as seguintes condições forem atendidas, a transformação continuará sem perda de informações:

  • O arquivo usado para construir o objeto Image é um arquivo JPEG.
  • A largura e a altura da imagem são múltiplos de 16.

Se a largura e a altura da imagem não forem múltiplos de 16, o GDI+ fará o possível para preservar a qualidade da imagem quando você aplicar uma das transformações de rotação ou inversão mostradas na lista anterior.

Para transformar uma imagem JPEG, inicialize um objeto EncoderParameters e passe o endereço desse objeto para o método Save da classe Image. Inicialize o objeto EncoderParameters para que ele tenha uma matriz que consiste em um objeto EncoderParameter. Inicialize esse objeto EncoderParameter para que seu membro Value aponte para uma variável de ULONG que contém um dos seguintes elementos da enumeraçãoEncoderValue:

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

Defina o Guid membro do objetoEncoderParametercomo EncoderTransformation.

O aplicativo de console a seguir cria um objeto Image de um arquivo JPEG e salva a imagem em um novo arquivo. Durante o processo de salvamento, a imagem é girada 90 graus. Se a largura e a altura da imagem forem múltiplos de 16, o processo de girar e salvar a imagem não causará perda de informações.

A função principal depende da função auxiliar GetEncoderClsid, que é mostrada em Recuperando o Identificador de Classe para umde Codificador.

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