2013-01-29 4 views
2
에서 WIC를 사용하여 무손실 JPG를 만들 수

나는 다음과 같은 코드가 디폴트 옵션이있는 IWICBitmapSource 중 JPG 파일 생성하기 위해 노력하고 있습니다어떻게 델파이

function SaveWICBitmapToJpgFile(WICFactory: IWICImagingFactory; 
    WICBitmap: IWICBitmapSource; SrcRect: TRect; FileName: string): HRESULT; 
var 
    hr: HRESULT; 
    Encoder: IWICBitmapEncoder; 
    Frame: IWICBitmapFrameEncode; 
    PropBag: IPropertyBag2; 
    S: IWICStream; 
    PixelFormatGUID: WICPixelFormatGUID; 
    R: WICRect; 
begin 

    hr := WICFactory.CreateStream(S); 

    if Succeeded(hr) then begin 
    hr := S.InitializeFromFilename(PChar(FileName), GENERIC_WRITE); 
    end; 

    if Succeeded(hr) then begin 
    hr := WICFactory.CreateEncoder(GUID_ContainerFormatJpeg, GUID_NULL, 
     Encoder); 
    end; 

    if Succeeded(hr) then begin 
    hr := Encoder.Initialize(S, WICBitmapEncoderNoCache); 
    end; 

    if Succeeded(hr) then begin 
    hr := Encoder.CreateNewFrame(Frame, PropBag); 
    end; 

    if Succeeded(hr) then begin 
    hr := Frame.Initialize(PropBag); 
    end; 

    if Succeeded(hr) then begin 
    hr := Frame.SetSize(SrcRect.Width, SrcRect.Height); 
    end; 

    if Succeeded(hr) then begin 
    PixelFormatGUID := GUID_WICPixelFormat24bppBGR; 
    hr := Frame.SetPixelFormat(PixelFormatGUID); 
    end; 

    if Succeeded(hr) then begin 
    hr := IfThen(PixelFormatGUID = GUID_WICPixelFormat24bppBGR, S_OK, E_FAIL); 
    end; 

    if Succeeded(hr) then begin 
    R.X := SrcRect.Left; 
    R.Y := SrcRect.Top; 
    R.Width := SrcRect.Width; 
    R.Height := SrcRect.Height; 
    Frame.WriteSource(WICBitmap, @R); 
    end; 

    if Succeeded(hr) then begin 
    hr := Frame.Commit; 
    end; 

    if Succeeded(hr) then begin 
    hr := Encoder.Commit; 
    end; 

    Result := hr; 

end; 

가 나는를 생산하는 코덱 옵션을 변경하려면를 무손실 jpg. MSDN에서 읽은 것을 이해함에 따라 IPropertyBag2를 사용해야합니다. 그것을 수행하는 방법에 대한 단서를 가지고 있지에도 불구하고, 나는 프레임 생성 및 프레임 초기화 사이에이 코드를 삽입하는 시도 :

var 
[...] 
    PropBagOptions: TPropBag2; 
    V: Variant; 
[...] 

if Succeeded(hr) then begin 
    FillChar(PropBagOptions, SizeOf(PropBagOptions), 0); 
    PropBagOptions.pstrName := 'ImageQuality'; 
    V := 1.0; 
    hr := PropBag.Write(1, @PropBagOptions, @V); 
end; 

그것은 작동하지 않았다 : 시간 = 0x88982F8E (WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE). MSDN에서는 here이 "ImageQuality"속성의 유형이 VT_R4라고 말하지만 이전에는 Variant를 사용하지 않았으므로 어떻게 작성해야할지 모르겠습니다. 압축이 실제로 무손실인지 확실하지 않습니다.

품질이 1.0 jpg가되도록 코드를 수정할 수 있으며 무손실입니까?

답변

3

경험이 없지만 링크 된 문서를 읽는 것이 가장 좋습니다. 모든

첫째, 난 당신이 PropBagOptions의 구성원을 더 지정할 필요가 있다고 생각 :

  • dwTypePROPBAG2_TYPE_DATA로 설정해야합니다.
  • vtVT_R4으로 설정해야합니다.

변형이 실제로 VT_R4인지 확인해야합니다. 델파이 용어로는 4 바이트 실제이고, 변형은 varSingle입니다.

V := VarAsType(1.0, varSingle); 

나는 그것을 완료해야한다고 생각합니다. 모두 함께 퍼팅

, 그것은 다음과 같습니다

JPEG 품질 1.0 무손실인지 여부에 관하여
FillChar(PropBagOptions, SizeOf(PropBagOptions), 0); 
PropBagOptions.pstrName := 'ImageQuality'; 
PropBagOptions.dwType := PROPBAG2_TYPE_DATA; 
PropBagOptions.vt := VT_R4; 
V := VarAsType(1.0, varSingle); 
hr := PropBag.Write(1, @PropBagOptions, @V); 

, 그것은 아닙니다. 이 질문은 이미 여기에서 다루고 있습니다. Is JPEG lossless when quality is set to 100?

+0

정말 좋은 추측처럼 보입니다. –

+0

작동 중입니다. 고마워요! PropBagOptions와 변형 모두에서 유형을 지정해야한다는 것을 알지 못했습니다. 나는 공식 소스에서 찾을 수 없기 때문에 PROPBAG2_TYPE_DATA를 선언해야했습니다. 나는 그것을 놓쳤는가? – Papaya

+0

반가워요. 받아 줘서 고마워. –