2012-02-26 60 views
5

我尝试在imgQInput(它是一个TImage)中加载图像,将其分配给TJpegImage,压缩它(压缩系数5)并在imgQOutput(另一个TImage)中显示它。但它不起作用。 imgQOutput中的图像与原始图像相同。它应该看起来非常像素化,因为压缩因子!然而,压缩的作品,因为当我将JPEG保存到磁盘时,它确实很小。无法压缩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; 
+2

TJpegImage保存位图DIB以及JPegData,即使压缩工作和保存到文件/流保存压缩的JPeg,将它分配给TImage.Picture使用DIB而不是原始图像,Vahid's答案是有效的,因为他已经从流中重新加载了JPeg,从而清除了DIB。 – Dampsquid 2012-02-26 20:59:12

+0

感谢Dampsquid。还有另一种方式来做到这一点,而无需从流中重新加载它?像JpegNeeded或左右? – Ampere 2012-02-26 21:32:37

+0

我从来没有找到一个,DIBNeeded只创建一个,如果没有一个,并且分配给新的TJPegImage也分配DIB,所以也不起作用。 – Dampsquid 2012-02-26 21:54:38

回答

6

你根本没有使用压缩过的JPG。

变化CompressJpeg为如下:(!记住,图像可能很大)

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; 
+0

它的工作原理。谢谢。你能解释一下吗? – Ampere 2012-02-26 20:59:33

+0

不客气。当您压缩/保存TJpegImage实例时,它不会影响原始缓冲区。所以你需要用新创建的jpeg流重新加载'OutJPG'来更新缓冲区。 – 2012-02-26 21:04:10

+0

但是,当我将OutJPG保存到磁盘时,图像被压缩。所以,改变了一些东西。 – Ampere 2012-02-26 21:30:45

3

这是给你一个竞争的答案,以较少的数据耍弄

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; 

TJPEGImage.FreeBitmap部署挥发性DIB内所含TJPEGImage实例。在图示的情况下,这导致班级最近对TImage刷新作出响应而解码出JPEG JPEG文件。

+0

FreeBitmap部分是干什么的? (授予?) – 2012-02-27 13:50:32

+0

@LeonardoHerrera,对答案补充说。 – OnTheFly 2012-02-27 14:37:30

+0

明白了,谢谢! – 2012-02-27 16:05:37