2

デフォルトのオプションを使用して、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;

動作しませんでした:hr = 0x88982F8E(WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE)。MSDNによると、「ImageQuality」プロパティのタイプはVT_R4ですが、これまでVariantを使用したことがないため、その記述方法がわかりません。そして、圧縮が実際にロスレスになるかどうかさえわかりません。

コードを変更して、高品質の1.0 jpgを生成するにはどうすればよいですか?ロスレスになりますか?

4

1 に答える 1

3

私はこれを経験していませんが、あなたがリンクしているドキュメントを読んだことに基づいた私の最良の提案は次のとおりです。

まず、次のメンバーをさらに指定する必要があると思いますPropBagOptions

  • dwTypeに設定する必要がありますPROPBAG2_TYPE_DATA
  • vtに設定する必要がありますVT_R4

また、バリアントが実際に であることを確認する必要がありVT_R4ます。これは 4 バイトの実数で、Delphi 用語では type のバリアントですvarSingle

V := VarAsType(1.0, varSingle);

私はそれを成し遂げるべきだと思います。

すべてをまとめると、次のようになります。

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);

JPEG 品質 1.0 が可逆であるかどうかに関しては、そうではありません。これは、ここですでに十分に説明されている質問です:品質が 100 に設定されている場合、JPEG はロスレスですか?

于 2013-01-29T14:34:28.150 に答える