2012-02-26 2 views
5

이미지를 imgQInput (TImage)에로드하고 TJpegImage에 할당하고 압축 (압축률 5)하고 imgQOutput (다른 TImage)에 표시하려고합니다. 그러나 그것은 효과가 없습니다. imgQOutput의 이미지는 원본과 같습니다. 그것은 압축 요소 때문에 매우 pixelated 봐야합니다! 그러나 압축은 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는 압축이 작동하고 파일/스트림에 저장하면 압축 된 JPeg를 저장하고 TImage에 할당하더라도 비트 맵 DIB와 JPegData를 모두 보유합니다. 그림 대신 원본 이미지 인 Vahid 's를 그대로두고 DIB를 사용합니다. 대답은 스트림에서 JPEG를 다시로드하여 DIB를 지우므로 작동합니다. – Dampsquid

+0

Dampsquid에게 감사드립니다. 스트림에서 다시로드하지 않고도이를 수행 할 수있는 또 다른 방법이 있습니까? Jpeg 필요합니까? – Ampere

+0

나는 하나도 찾지 못했고 DIBNeeded는 이미 하나가없는 경우에만 DIBNeeded를 생성하고, 새로운 TJPegImage에 할당하면 DIB도 할당하므로 나도 작동하지 않습니다. – Dampsquid

답변

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

+0

당신을 진심으로 환영합니다. TJpegImage 인스턴스를 압축/저장할 때 원래 버퍼에는 영향을 미치지 않습니다. 따라서 버퍼를 업데이트하기 위해 새로 생성 된 jpeg 스트림으로 'OutJPG'를 다시로드해야합니다. –

+0

그러나 OutJPG를 디스크에 저장하면 이미지가 압축됩니다. 그래서 무언가가 바뀌 었습니다. – Ampere

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의 재 묘화에 대한 응답으로 최근에 .Compress의 JPEG를 디코딩하게됩니다.

+0

'FreeBitmap' 부분은 무엇을합니까? (수여) –

+0

@ 레오나르도 헤레라는 대답에 덧붙여 말했습니다. – OnTheFly

+0

알겠습니다. 고마워요! –

관련 문제