Сохранить изображение в различных форматах файлов - PullRequest
7 голосов
/ 07 сентября 2011

У меня есть подпрограмма procedure DrawStuff(ACanvas: TCanvas; const ARect: TRect), которая рисует что-то в указанном прямоугольнике на TCanvas.На данный момент я звоню DrawStuff с холстом PaintBox.Теперь я добавляю опцию Save as, в которой пользователь сможет выбирать из множества форматов файлов (bmp, wmf, jpg, ... - предпочтительно столько потомков TGraphic, сколько возможно), чтобы сохранить результатыDrawStuff to.

Рисование в TMetafile и сохранение этого файла в виде "bla.bmp" или Assign в TPicture работает неправильно - например, он создает файлы с расширением ".bmp ", что не являются растровыми изображениями.Сейчас я не могу найти решение, которое не включает в себя специальный регистр для каждого отдельного формата файла:

  • bmp - Используйте TBitmap.Canvas.
  • wmf / emf: Use TMetafileCanvas.
  • и т. Д.и т.д.

Знаете ли вы, есть идеи для меня?

1 Ответ

10 голосов
/ 07 сентября 2011

Полагаю, что "глупое" преобразование будет таким простым:

type
  TGraphicTypeEnum = (gteBMP, gteJPG, gteTIF, gtePNG);

procedure SaveGraphicAs(AGraphic : TGraphic; AGraphicType : TGraphicTypeEnum; AFileName : String);
var vGraphicClass : TGraphicClass;
    vTargetGraphic : TGraphic;
    vBmp : TBitmap;
begin

  case AGraphicType of
    gteBMP : vGraphicClass := TBitmap;
    gtejpg : vGraphicClass := TJPEGImage;
    gtetif : vGraphicClass := TWICImage;
    gtepng : vGraphicClass := TPngImage;
  else
    // EXIT; or raise...
  end;
  if aGraphic is vGraphicClass then //As suggested by Rob Kennedy
    AGraphic.SaveToFile(AFileName)
  else
  begin
    vBmp := nil;
    vTargetGraphic := vGraphicClass.Create;
    try
      vBmp := TBitmap.Create;
      vBmp.Assign(AGraphic);
      vTargetGraphic.Assign(vBmp);
      vTargetGraphic.SaveToFile(aFileName);
    finally
      vTargetGraphic.Free;
      vBmp.Free;
    end;
  end;
end;

Присвоение TPicture не сработало, так как при назначении TPicture TPicture преобразует рисунок в класс, из которого вы назначаете.

Обратите внимание, что в моем примере есть 2 слоя преобразования, поскольку исходное изображение преобразуется в растровое изображение перед преобразованием в окончательный формат. При этом может происходить небольшая потеря информации. Большинство (все?) Графических типов знают, как конвертировать в TBitmap и из TBitmap, но TJPEGImage не знает, как конвертировать в TPngImage и наоборот.

Может быть разработан более эффективный метод преобразования, который сохраняет прозрачность и другие эффекты, специфичные для формата файла, но это вне моих знаний. Но, в зависимости от ваших потребностей, этого может быть достаточно.

...