如何正确地将Timage位图分配给jpg?

3
我正在尝试调整 Timage 图像的大小并将其保存为 jpg。但是,保存的图像出现了空白。
以下是我分配 Timage 的方式:
begin
 with TOpenDialog.Create(self) do
    try
      Caption := 'Open Image';
      Options := [ofPathMustExist, ofFileMustExist];
      Filter  := 'JPEG Image File (*.jpg)|*.jpg|JPEG Image File (*.jpeg)|*.jpeg|Bitmaps (*.bmp)|*.bmp';
      if Execute then
        image1.Picture.LoadFromFile(FileName);
    finally
      Free;
    end;
end;

以下是我调整图片大小并将其分配到JPG文件中的方法。

 with Image2.Canvas do begin
    Lock;
    try
      try
        Image2.Picture.Graphic.Width := 50;
        Image2.Picture.Graphic.Height := 50;
        FillRect(ClipRect);
        StretchDraw(rect(0, 0, 50, 50), image1.Picture.Bitmap);
      except
        on E: Exception do
//log

      end;
    finally
      Unlock;
    end;
  end;




Jpg := TJPEGImage.Create;
try

Jpg.Performance := jpBestSpeed;
Jpg.ProgressiveEncoding := True;
Jpg.ProgressiveDisplay := True;
Jpg.Assign(image2.Picture.Bitmap);
Jpg.CompressionQuality := 90;
Jpg.Compress;
jpg.SaveToFile('screena.jpg');



finally
Jpg.Free;
end;

保存的 jpg 变成了空白,我做错了什么?我只需要从磁盘中加载图像到 Timage,然后调整宽度和高度,并再次分配到 jpg 中。

1
你为什么要使用TImage?那是一个GUI控件。 - David Heffernan
1
可能是因为图像正在展示给用户。使用TOpenDialog意味着正在使用UI。无论如何,TImage2并不是真正需要的,可以用简单的TBitmap替换:bmp := TBitmap.Create; try bmp.Width := 50; bmp.Height := 50; bmp.Canvas.StretchDraw(rect(0, 0, 50, 50), image1.Picture.Graphic); ... Jpg.Assign(bmp); ... finally bmp.Free; end; - Remy Lebeau
1个回答

5
你的图片无法显示是因为你在将 Image1 绘制到 Image2 的画布上时使用了 Picture.Bitmap 属性:
StretchDraw(rect(0, 0, 50, 50), image1.Picture.Bitmap);

如果您没有加载 .bmp 文件到 Image1 中,访问 Bitmap 属性将会清除当前的图像并用一个空白图像进行替换。这是一种被记录下来的行为:documented behavior

当图片对象含有位图时,使用 Bitmap 引用该图片对象。如果当图片包含元文件或图标图形时引用 Bitmap,图形将不会被转换 (Types of Graphic Objects)。相反,图片的原始内容将被丢弃,并且 Bitmap 返回一个新的空白位图

TCanvas.StretchDraw() 方法可以接受任何 TGraphic 对象作为其第三个参数。您应该传递 Picture.Graphic 属性而不是 Picture.Bitmap 属性:
StretchDraw(rect(0, 0, 50, 50), image1.Picture.Graphic);

顺便提一下:在分配TOpenDialog.Filter属性时,考虑使用VCL的Graphics单元中的GraphicFilter()函数:

返回与打开或保存对话框的Filter属性兼容的文件过滤器。

调用GraphicFilter以获取适用于打开、打开图片、保存图片或保存对话框框的Filter属性的值。 GraphicClass参数可以指定以下值之一:TBitmapTGraphicTIconTMetafileTGraphic的用户定义后代。

例如:

Filter := GraphicFilter(TGraphic);

如果您要手动填写Filter,那么至少不要为不同的JPEG扩展名创建单独的条目。请将它们组合在一个条目中,例如:

Filter  := 'JPEG Images (*.jpg, *.jpeg)|*.JPG;*.JPEG|Bitmap Images (*.bmp)|*.BMP';

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接