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之间,不需要存储得那么大,因为它们只能在电脑屏幕上观看。我想把它们缩小到想要的尺寸,比如1920 x 1080,并保持高宽比。如果图像已经小于1920 x 1080,我不想缩小图像。
我已经做了很多的搜索,尝试和错误,到目前为止只有错误。当用户手动工作时,我有缩放和/或旋转后的保存部分。但我希望能够扫描整个数据库并随时更改大小。
一个代码片段会很好。
您只需要遍历文件名列表,并对每个文件名执行调整大小的代码。作为一个简单的开始。。。
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
。报告异常也是一个好主意,因此我还包括了非常简单的错误报告。不过,您肯定希望对此进行扩展,例如实现进度条。
如果这是针对生产环境的,例如您打算分发甚至销售的东西,您可能需要考虑为此类任务使用单独的线程。
我也强烈建议不要覆盖现有的图像,以防万一。实现某种输出目录,并将新调整大小的图像保存在那里。
这个答案是基于您的编辑标记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;
Bmp
、Jpg
和Dst
变量需要在try
之前被置零,以防止使用未初始化的内存引用最终调用Free
。如果在创建所有三个对象之前,任何代码都会引发异常,则可能会发生这种情况。