Delphi 无法压缩JPEG图像并在屏幕上显示

Delphi 无法压缩JPEG图像并在屏幕上显示,delphi,Delphi,我尝试在imgQInput(这是一个TImage)中加载一个图像,将其分配给一个TJPEG图像,压缩它(压缩因子5),并在imgQOutput(另一个TImage)中显示它。但它不起作用。imgQOutput中的图像与原始图像相同。它应该看起来非常像素化,因为压缩因子!但是,压缩可以工作,因为当我将JPEG保存到磁盘时,它非常小 JPG:= TJPEGImage.Create; TRY JPG.CompressionQuality:= trkQuality.Position;

我尝试在imgQInput(这是一个TImage)中加载一个图像,将其分配给一个TJPEG图像,压缩它(压缩因子5),并在imgQOutput(另一个TImage)中显示它。但它不起作用。imgQOutput中的图像与原始图像相同。它应该看起来非常像素化,因为压缩因子!但是,压缩可以工作,因为当我将JPEG保存到磁盘时,它非常小

  JPG:= TJPEGImage.Create;
   TRY
     JPG.CompressionQuality:= trkQuality.Position;
     JPG.Assign(imgQInput.Picture.Graphic);
     CompressJpeg(JPG);
     imgQOutput.Picture.Assign(JPG);          <--------- something wrong here. the shown image is not the compressed image but the original one
   FINALLY
     FreeAndNil(JPG);
   END;


function CompressJpeg(OutJPG: TJPEGImage): Integer;
VAR tmpQStream: TMemoryStream;
begin
 tmpQStream:= TMemoryStream.Create;
 TRY
   OutJPG.Compress;
   OutJPG.SaveToStream(tmpQStream);
   OutJPG.SaveToFile('c:\CompTest.jpg');       <--------------- this works
   Result:= tmpQStream.Size;
 FINALLY
   FreeAndNil(tmpQStream);
 END;
end;
JPG:=TJPEGImage.Create;
尝试
JPG.压缩质量:=trkQuality.位置;
分配(imgQInput.Picture.Graphic);
压缩JPEG(JPG);

imgQOutput.Picture.Assign(JPG) 您根本没有使用压缩的JPG

更改
压缩JPEG
,如下所示:

function CompressJpeg(OutJPG: TJPEGImage): Integer;
VAR tmpQStream: TMemoryStream;
begin
 tmpQStream:= TMemoryStream.Create;
 TRY
   OutJPG.Compress;
   OutJPG.SaveToStream(tmpQStream);
   OutJPG.SaveToFile('c:\CompTest.jpg');    // You can remove this line.
   tmpQStream.Position := 0;                //
   OutJPG.LoadFromStream(tmpQStream);       // Reload the jpeg stream to OutJPG
   Result:= tmpQStream.Size;
 FINALLY
   FreeAndNil(tmpQStream);
 END;
end;

这里有一个与之竞争的答案,数据处理较少(请记住,图像可能很大!)


TJPEGImage.FreeBitmap
处理TJPEGImage实例中包含的易失性DIB。在图示的情况下,这会导致类最近解码
。压缩
“Eded JPEG,以响应
TImage
重新绘制。

TJpegImage保存位图DIB和JPEG数据,即使压缩有效且保存到文件/流保存压缩的JPEG,将其分配给TImage。Picture使用DIB,而不是将原始图像留给您,Vahid的回答有效,因为他已从流中重新加载JPeg,从而清除了DIB。谢谢Dampsquid。还有另一种方法可以不从流中重新加载它吗?像JPEG需要吗?我从来没有找到一个,DIBNeeded只在没有的情况下创建一个,分配给新的TJPegImage也会分配DIB,这样也不起作用。不客气。压缩/保存TJpegImage实例时,不会影响原始缓冲区。因此,您需要使用新创建的jpeg流重新加载
OutJPG
,以更新缓冲区。所以,有些东西被改变了。@DavidHeffernan,错了,JPEG远远不仅仅是一个过滤器。事实上,这个类非常懒惰,直到人们每次试图争论他们不理解的事情时,
JPEGNeeded
@DavidHeff,才执行编码;-)现在,您正在从“是”倒退到“可能”,现在请慢慢阅读JPEG压缩,以及为什么它不是流过滤器。否则,请解释您的兴趣,但请记住网站的口号-要具体。@DavidHeffernan,我告诉过您要具体,除了通常未公开给公共范围的方法来指示类丢失其自愿DIB数据之外,它没有什么棘手的地方。而且您仍然在重复错误的信息,Compress(公共的和有良好文档记录的!)方法指示类执行上述向量和矩阵变换。而且没有流。
freebimat
部分做什么?(协商?)@user539484。您的答案似乎不错,但它遗漏了一点:它没有告诉压缩图像的大小。我的函数“CompressJpeg”会执行此操作。@user539484-此应用程序已泄漏内存。小数据块泄漏(不包括指针注册的预期泄漏):21-36字节:TJPEGData x 2,TMemoryStream x 2 69-84字节:TJPEGImage x2@Altar,已确认一个TJPEG图像/TJPEG数据对泄漏,其他在别处。
type
  TJPEGExposed = class(TJPEGImage);     // unfortunately, local class declarations are not allowed

procedure TForm1.FormClick(Sender: TObject);
var
  JPEGImage: TJPEGImage;
const
  jqCrappy = 1;
begin
  Image1.Picture.Bitmap.LoadFromFile(GetDeskWallpaper);

  Image2.Picture.Graphic := TJPEGImage.Create;
  JPEGImage := Image2.Picture.Graphic as TJPEGImage;    // a reference
  JPEGImage.Assign(Image1.Picture.Bitmap);
  JPEGImage.CompressionQuality := jqCrappy;    // intentionally
  JPEGImage.Compress;
  TJPEGExposed(JPEGImage).FreeBitmap;    { confer: TBitmap.Dormant }
end;