如何将大的图片缩小成小图片,要失真尽量少(200分)

  • 主题发起人 主题发起人 zbsfg
  • 开始时间 开始时间
Z

zbsfg

Unregistered / Unconfirmed
GUEST, unregistred user!
我用StretchDraw失真,StretchBlt失真得列夸张,copyrecT简单不能看,有没有真正好的办法实现无损缩小
Bmp.Canvas.StretchDraw(Bounds(0,0, Bmp.Width,Bmp.Height),Bitmap);
StretchBlt(Bmp.Canvas.Handle,0,0,Bmp.Width,Bmp.Height,
Bitmap.Canvas.Handle,0,0,Bitmap.Width,Bitmap.Height,SRCCOPY);

另外,关于内存泄漏
function Bmp2Jpg(Bmp: TBitmap; Quality: Integer = 100): TJpegImage;
begin
Result := nil;
if Assigned(Bmp)
then begin
Result := TJpegImage.Create; //只有创建,没看过他FREE,会不会有内存泄漏
Result.Assign(Bmp); {Its all folks...}
...
end;

 
使用Image 控件即可.但要考虑控件的宽度与高度,再考虑图片的宽度与高度,然后按比例缩放即可.
var
l1,t1:integer;
pw,ph,iw,ih,fw,fh:Integer;
begin
Screen.Cursor:=crHourGlass;
iw:=0;
ih:=0;

Image1.Stretch:=False;
fw:=FormShow.Width;
fh:=FormShow.Height;
pw:=Image1.Picture.Width;
ph:=Image1.Picture.Height;

if (fw>=pw) and (fh>=ph) then
begin
iw:=pw;
ih:=ph;
end;

if (fw>=pw) and (fh<ph) then
begin
ih:=fh;
iw:=Round(pw*ih/ph);
end;

if (fw<pw) and (fh>=ph) then
begin
iw:=fw;
ih:=Round(ph*iw/pw);
end;

if (fw<pw) and (fh<ph) then
begin
if fw<fh then
begin
iw:=fw;
ih:=Round(ph*iw/pw);
end;
if fw>=fh then
begin
ih:=fh;
iw:=Round(pw*ih/ph);
end;
end;

l1:=Round((fW-iw)*0.5);
t1:=Round((fh-ih)*0.5);
if l1<0 then l1:=0;
if t1<0 then t1:=0;
Image1.Left:=l1;
Image1.Top:=t1;
Image1.Width:=iw;
Image1.Height:=ih;

Image1.Stretch:=True;
Screen.Cursor:=crDefault;

end;
 
我试过效果不错的:
procedure ZoomImg(Img, SecondPic: TImage; var xTimes, yTimes: real);
var
Bmp: TBitmap;
begin
Bmp := TBitmap.Create;
if (xTimes > 0) and (yTimes > 0) then
begin
Bmp.Width := round(Img.Picture.Bitmap.Width * xTimes);
Bmp.Height := round(Img.Picture.Bitmap.Height * yTimes);
SetStretchBltMode(Bmp.Canvas.Handle, HALFTONE); //加此句效果好
StretchBlt(Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height,
Img.Picture.Bitmap.Canvas.Handle, 0, 0, Img.Picture.Bitmap.Width, Img.Picture.Bitmap.Height, SRCCOPY);
SecondPic.Picture.Bitmap.Assign(Bmp);
SecondPic.AutoSize := True;
end;
Bmp.Free;
end;
 
to linsb,
加了后和StretchDraw效果一样,失真,我要再好一些
 
to :zbsfg
1:位图都会有损,因为在放大或缩小时会拉开点阵或丢弃一些点信息,
比如BMP, JPEG, GIF, TIFF等。
要想效果好,需要用颜色逼近算法计算扫描线之间的渐进色。

2:用矢量图就可以随意缩放了,因为矢量图是用描述法产生信息的。
比如DWG,EMF, WMF等,在Windows下通称为MetaFile(元文件),具体内容可
参阅MSDN下的GDI和GDI Plus一节。
 
jcl里面有个这种函数,你找来看看.
 
有没有现成的算法或控件??

 
用JPG自身的Jpeg.Scale:=jsHalf;可以缩小一半,没失真,但它一次只能缩小为1/2,1/4,1/8
不能自定义缩小比例

Determines the size of the JPEG image when it is displayed.

type TJPEGScale = (jsFullSize, jsHalf, jsQuarter, jsEighth);
property Scale: TJPEGScale;

Description

Use Scale to optimize performance for previewing an image. jsFullSize displays the image as maximum size, whereas jsEighth displays an eighth of the image size, but 8 times faster.

jsHalf
isplays a half-size image in half the time it takes to display a full-sized image.
jsQuarter
Displays a quarter-size image in a quarter of the time it takes to display a full-sized image.
jsEighth
Displays an eighth-size image in an eighth of the time it takes to display a full-sized image.
 
用DrawDib这个函数组吧,上屏速度快,失真小!
 
只好用第三方控件了
 
后退
顶部