Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Delphi中使用WIC创建无损jpg_Delphi_Wic - Fatal编程技术网

如何在Delphi中使用WIC创建无损jpg

如何在Delphi中使用WIC创建无损jpg,delphi,wic,Delphi,Wic,我有以下代码使用默认选项从IWICBitmapSource创建jpg文件: function SaveWICBitmapToJpgFile(WICFactory: IWICImagingFactory; WICBitmap: IWICBitmapSource; SrcRect: TRect; FileName: string): HRESULT; var hr: HRESULT; Encoder: IWICBitmapEncoder; Frame: IWICBitmapFrame

我有以下代码使用默认选项从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,但因为我以前从未使用过变体,所以我不知道如何编写它。我甚至不确定压缩是否真的是无损的


我如何修改我的代码,使其生成高质量的1.0 jpg,并且它将是无损的?

我没有这方面的经验,但以下是我在阅读您链接的文档的基础上提出的最佳建议

首先,我认为您需要指定
PropBagOptions
的更多成员:

  • dwType
    需要设置为
    PROPBAG2\u TYPE\u DATA
  • vt
    需要设置为
    vt\u R4
您还需要确保变体确实是
VT\u R4
。这是一个4字节的实数,用Delphi术语来说是类型
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 quality 1.0是否是无损的,它不是。这是一个已经在这里讨论过的问题:

它正在工作。谢谢!我甚至没有意识到我必须在PropBagOptions和variant中指定类型:|但是我必须声明PROPBAG2_type_数据,因为我在官方来源中找不到它。我错过了吗?