Graphics32:调整大量图片的大小

时间:2016-03-23 22:52:16

标签: delphi delphi-5 graphics32

2016年3月24日 我76岁,当我写这篇文章时我觉得它很有道理,但和其他人一样,我不确定我在问什么。这是我在网上搜索拼凑的(不是很漂亮)。 几乎有效,唯一缺少的是保留宽高比。它使高大的照片看起来很胖。在40年的编程中,我总共有两个小时的编码图形。 :)

procedure TfrmTools.Shrink(aFn : String; Wid,Ht : Integer);
var
  Bmp : TBitmap;    // These three are created
  Jpg : TJpegImage; //  and Freed globally
  Dst : TBitmap32;  //  to save some bit-thrashing
begin
  try
    Src.Bitmap.LoadFromFile(aFn);  // Src = TImage32
    Dst:=TBitmap32.Create;
    Dst.SetSize(Wid,Ht);
    Src.Bitmap.DrawTo(Dst,Dst.BoundsRect);
    bmp:=TBitmap.Create;
    jpg:=TJPEGImage.Create;
    bmp.Assign(Dst);
    jpg.Assign(bmp);
    jpg.SaveToFile('D:\Test1280x720.jpg');  // Just testing
  finally
    Bmp.Free;  // As above
    Jpg.Free;  // As above
    Dst.Free;  // As above
  end;
end;

2016年3月23日 我在这里接受了一个好心灵的建议,并用Graphis32咬了一口子,很高兴我做到了,但是撞墙了。我在数据库中有大约1200张图像的路径,并且一切都很适合显示,保存等。

有些图像介于6到9MB之间,不需要存储太大,因为它们只能在PC屏幕上观看。我想将它们缩小到所需的尺寸,比如1920 x 1080并保持H x W比率。如果图像已经小于1920 x 1080,我不想减少图像。

我做了很多搜索和试错,到目前为止只有错误。当用户手动工作时,我在缩放和/或旋转后有保存部分。但我希望能够扫描整个数据库并随时更改大小。

代码段很棒。

2 个答案:

答案 0 :(得分:1)

您只需遍历文件名列表并在每个文件名上执行调整大小代码。作为一个简单的开始...

function TForm1.ResizeImage(const Filename: String): String;
begin
  Result:= '';
  try

    //Your resizing code here

  except
    on e: Exception do begin
      Result:= e.Message;
    end;
  end;
end;

procedure TForm1.ResizeAllImages(const List: TStringList);
var
  X: Integer;
  R: String;
begin
  for X := 0 to List.Count - 1 do begin
    R:= ResizeImage(List[X]);
    if R <> '' then begin
      //Report error in a memo control
      Memo1.Lines.Add(List[X]);
      Memo1.Lines.Add(R);
      Memo1.Lines.Add('');
    end;
  end;
end;

将文件名列表加载到TStringList中,然后调用传递此字符串列表的ResizeAllImages。报告异常也是一个好主意,因此我还包括非常简单的错误报告。您肯定希望扩展这一点,例如实施进度条。

如果这是针对生产环境的,例如您打算分发甚至销售的东西,您可以考虑使用单独的线程来执行此类任务。

我还强烈建议不要覆盖现有图像,以防万一。实现某种输出目录,并在那里保存新调整大小的图像。

答案 1 :(得分:1)

此答案基于您标记为3/24/2016的编辑,您可以在调整大尺寸图片时说明剩下的问题是缺少宽高比。假设两个参数Wid, Ht: integer是要应用的最大宽度和高度,我建议使用注释标记以下更改:

procedure TfrmTools.Shrink(aFn : String; Wid,Ht : Integer);
var
  Bmp : TBitmap;    // These three are created
  Jpg : TJpegImage; //  and Freed globally
  Dst : TBitmap32;  //  to save some bit-thrashing
  DstWidth, DstHeight: integer; // Add
  AspRatio: single;             // Add
begin
  Bmp := nil;  // not related to your question, see comment in text
  Jpg := nil;  // -"-
  Dst := nil;  // -"-
  try
    Src.Bitmap.LoadFromFile(aFn);  // Src = TImage32

  // Add following lines
  DstWidth := Src.Width;
  DstHeight := Src.Height;
  AspRatio := Src.Width/Src.Height;

  if (DstWidth > Wid) then
  begin
    DstWidth := Wid;
    DstHeight := round(DstWidth / AspRatio);
  end;

  if (DstHeight > Ht) then
  begin
    DstHeight := Ht;
    DstWidth := round(DstHeight * AspRatio);
  end;
  // end of added lines

    Dst:=TBitmap32.Create;
//    Dst.SetSize(Wid,Ht); // Replace parameters
    Dst.SetSize(DstWidth,DstHeight);
    Src.Bitmap.DrawTo(Dst,Dst.BoundsRect);
    bmp:=TBitmap.Create;
    jpg:=TJPEGImage.Create;
    bmp.Assign(Dst);
    jpg.Assign(bmp);
    jpg.SaveToFile('D:\Test1280x720.jpg');  // Just testing
  finally
    Bmp.Free;  // As above
    Jpg.Free;  // As above
    Dst.Free;  // As above
  end;
end;

BmpJpgDst变量需要在try之前填充,以防止最终调用带有未初始化内存引用的Free。如果在创建所有三个对象之前的任何代码引发异常,则可能发生这种情况。