Graphics32:调整大量图像的尺寸

问题描述:

2016/3/24 我是76岁,当我写作时我认为这是有道理的,但是和其他人一样,我不确定我在问什么。这是我拼凑起来的(这并不漂亮)从互联网上冲刷出来。它几乎的作品,唯一缺少的是保持长宽比。它使高个子看起来很胖。在40年的编程中,我可能总共花了两个小时编码图形的东西。 :)Graphics32:调整大量图像的尺寸

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.

我已经做了大量的搜索和试验和错误,迄今只有错误。当用户正在手动工作时,缩放和/或旋转后,我有了“保存”部分。但我希望能够扫描整个数据库并随时更改大小。

代码片段会很棒。

+0

你到目前为止尝试过什么?向我们展示一些代码,或者在您卡住的部分询问具体问题。 – whosrdaddy

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

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传递这个字符串列表。报告异常也是一个好主意,因此我还包含了非常简单的错误报告。你一定要扩展这个,例如实现一个进度条。

如果这是针对生产环境的,例如您打算分发甚至销售的东西,那么您应该考虑为这些任务使用单独的线程。

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

+0

还有一个好习惯,首先加载图像头,它包含宽度和高度,因此可以决定是否需要加载该图像,或者我们可以立即移动到下一个图像。 –

+0

@YuriyAfanasenkov我不怀疑它,但根据这个问题,OP已经知道如何进行重新调整大小,只需要知道如何对1,200张图像进行批量处理。这将是一个不同的问题。 –

此答案基于您编辑标记为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之前nilled以防止最终调用Free未初始化内存引用。如果在创建所有三个对象之前有任何代码产生异常,就可能发生这种情况。