2012-02-26 81 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