Создание и сохранение многокадрового изображения

При использовании определенных форматов можно сохранить несколько изображений (фреймов) в одном файле. Например, можно сохранить несколько страниц в одном TIFF-файле. Чтобы сохранить первую страницу, вызовите метод Save класса Image . Чтобы сохранить последующие страницы, вызовите метод SaveAdd класса Image .

Примечание

Вы не можете использовать SaveAdd для добавления кадров в анимированный GIF-файл.

 

Следующее консольное приложение создает TIFF-файл с четырьмя страницами. Образы, которые становятся страницами TIFF-файла, поступают из четырех дисковых файлов: Shapes.bmp, Cereal.gif, Iron.jpg и House.png. Сначала код создает четыре объекта Image : multi, page2, page3 и page4. Сначала multi содержит только образ из Shapes.bmp, но в конечном итоге содержит все четыре изображения. По мере добавления отдельных страниц в объект multiImage они также добавляются в файл диска Multiframe.tif.

Обратите внимание, что код вызывает Save (а не SaveAdd) для сохранения первой страницы. Первый аргумент, передаваемый в метод Save, — это имя файла диска, который в конечном итоге будет содержать несколько кадров. Второй аргумент, передаваемый методу Save, указывает кодировщик, который будет использоваться для преобразования данных в объекте multiImage в формат (в данном случае TIFF), необходимый для файла диска. Этот же кодировщик используется автоматически при всех последующих вызовах метода SaveAdd объекта multiImage .

Третий аргумент, передаваемый в метод Save , — это адрес объекта EncoderParameters . Объект EncoderParameters имеет массив, содержащий один объект EncoderParameter . Элемент GUID этого объекта EncoderParameter имеет значение EncoderSaveFlag. Элемент Value объекта EncoderParameter указывает на ULONG , содержащий значение EncoderValueMultiFrame.

Код сохраняет вторую, третью и четвертую страницы, вызывая метод SaveAdd объекта multiImage . Первый аргумент, передаваемый в метод SaveAdd, — это адрес объекта Image . Изображение в этом объекте Image добавляется в объект multiImage , а также добавляется в файл диска Multiframe.tif. Второй аргумент, передаваемый в метод SaveAdd, — это адрес того же объекта EncoderParameters , который использовался методом Save . Разница заключается в том, что ULONG , на который указывает элемент Value , теперь содержит значение EncoderValueFrameDimensionPage.

Функция main использует вспомогающую функцию 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);

   EncoderParameters encoderParameters;
   ULONG             parameterValue;
   Status            stat;

   // An EncoderParameters object has an array of
   // EncoderParameter objects. In this case, there is only
   // one EncoderParameter object in the array.
   encoderParameters.Count = 1;

   // Initialize the one EncoderParameter object.
   encoderParameters.Parameter[0].Guid = EncoderSaveFlag;
   encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
   encoderParameters.Parameter[0].NumberOfValues = 1;
   encoderParameters.Parameter[0].Value = &parameterValue;

   // Get the CLSID of the TIFF encoder.
   CLSID encoderClsid;
   GetEncoderClsid(L"image/tiff", &encoderClsid);

   // Create four image objects.
   Image* multi = new Image(L"Shapes.bmp");
   Image* page2 = new Image(L"Cereal.gif");
   Image* page3 = new Image(L"Iron.jpg");
   Image* page4 = new Image(L"House.png");

   // Save the first page (frame).
   parameterValue = EncoderValueMultiFrame;
   stat = multi->Save(L"MultiFrame.tif", &encoderClsid, &encoderParameters);
   if(stat == Ok)
      printf("Page 1 saved successfully.\n");

   // Save the second page (frame).
   parameterValue = EncoderValueFrameDimensionPage;
   stat = multi->SaveAdd(page2, &encoderParameters);
   if(stat == Ok)
      printf("Page 2 saved successfully.\n");

   // Save the third page (frame).
   parameterValue = EncoderValueFrameDimensionPage;
   stat = multi->SaveAdd(page3, &encoderParameters);
   if(stat == Ok)
      printf("Page 3 saved successfully.\n");

   // Save the fourth page (frame).
   parameterValue = EncoderValueFrameDimensionPage;
   stat = multi->SaveAdd(page4, &encoderParameters);
   if(stat == Ok)
      printf("Page 4 saved successfully.\n");

   // Close the multiframe file.
   parameterValue = EncoderValueFlush;
   stat = multi->SaveAdd(&encoderParameters);
   if(stat == Ok)
      printf("File closed successfully.\n");

   delete multi;
   delete page2;
   delete page3;
   delete page4;
   GdiplusShutdown(gdiplusToken);
   return 0;
}