【问题标题】:Graphics32: resize a lot of imagesGraphics32:调整很多图像的大小
【发布时间】:2016-03-23 22:52:15
【问题描述】:

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,我不想缩小图像。

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

一个代码 sn-p 会很棒。

【问题讨论】:

    标签: delphi delphi-5 graphics32


    【解决方案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 传递此字符串列表。报告异常也是一个好主意,因此我还包括了非常简单的错误报告。不过,您肯定希望对此进行扩展,例如实现进度条。

    如果这是用于生产环境,例如您打算分发甚至销售的东西,您可能需要考虑为此类任务使用单独的线程。

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

    【讨论】:

    • 首先加载图片标题也是一个很好的做法,它包含宽度和高度,因此可以决定是否需要加载这张图片,或者我们可以立即移动到下一张。跨度>
    • @YuriyAfanasenkov 我不怀疑,但根据问题,OP 已经知道如何重新调整大小,只需要知道如何批量处理 1,200 张图像。那将是一个不同的问题。
    【解决方案2】:

    此答案基于您标记为3/24/2016 的编辑,您说剩下的问题是调整大图像大小时缺少纵横比。假设 Wid, Ht: integer 这两个参数是要应用的最大宽度和高度,我建议使用 cmets 进行以下更改:

    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。如果任何代码在创建所有三个对象之前引发异常,则可能发生这种情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 2012-11-30
      • 2020-05-10
      • 2011-10-24
      • 2010-11-20
      • 1970-01-01
      相关资源
      最近更新 更多