You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用libheif回调在Delphi中写入HEIF图像到字节数组遇错求助

问题:libheif通过回调写入字节数组失败

我正在将libheif库转换为Pascal代码,用于Delphi-Extended-Images-Format库,多数所需函数已完成转换,但在实现HEIF图像写入字节数组时遇到问题。

libheif提供heif_context_read_from_memory可轻松读取内存中的HEIF图像,但没有对应的heif_context_write_to_memory函数。通过相关资料得知,可通过heif_context_write配合写入回调实现该功能,我编写了如下代码:

const
  InputFile = 'C:\Test\sample.heic';
  OutputFile = 'output.heic';

var
  databytes: PByte;
  writer: THeifWriter;

var
  ctx: PHeifContext;
  imageHandle: PHeifImageHandle;
  encoder: PHeifEncoder;

  FImage: PHeifImage;
  FDataStride: integer;
begin
  // Allocate context
  ctx := heif_context_alloc();
  try
    // Make new memory instance
    heif_context_read_from_file(ctx, @AnsiString(InputFile)[1], nil).ErrRaise;

    // Get primary image
    heif_context_get_primary_image_handle(ctx, imageHandle).ErrRaise;
    try
      // Decode image
      heif_decode_image(imageHandle, FImage, THeifColorspace.colorspace_RGB, THeifChroma.chroma_interleaved_RGB, nil).ErrRaise;

      // Read plane
      heif_image_get_plane(FImage, THeifChannel.channel_interleaved, FDataStride);
    finally
      heif_image_handle_release(imageHandle);
    end;
  finally
    heif_context_free( ctx );
  end;

  // Encode
  ctx := heif_context_alloc();
  try
    // Crete encoder
    heif_context_get_encoder_for_format(ctx, THeifCompressionFormat.compression_HEVC, encoder).ErrRaise;
    try
      // Set quality
      heif_encoder_set_lossless(encoder, true).ErrRaise;

      // Encode
      heif_context_encode_image(ctx, FImage, encoder, nil, nil).ErrRaise;
    finally
      heif_encoder_release(encoder);
    end;

    // Write
    databytes := AllocMem(sizeof(byte));
    databytes^ := 123;

    writer.writer_api_version := 1;
    writer.write := writer_write;
    heif_context_write(ctx, writer, databytes);
  finally
    heif_context_free(ctx);
  end;

对应的回调函数代码:

function TForm1.writer_write(ctx: PHeifContext; const data: Pointer;
  size: cardinal; userdata: Pointer): THeifError;
var
  value: int64;
  MemoryZone: PByte;
begin
  // Allocate memory
  MemoryZone := AllocMem(size);
  try
    Move(data, MemoryZone, size);
  finally
    FreeMem(MemoryZone, size);
  end;

  // Result
  Result := THeifError.Create(THeifErrorNum.heif_error_Invalid_input);
end;

目前遇到的问题:回调函数中的Move()过程报错,且size参数的值始终看似随机。但使用heif_context_write_to_file(ctx, @AnsiString(OutputFile)[1])替代heif_context_write时,图像可正常保存,说明编码器和文件读取逻辑均无问题。查阅大量示例和文档后,关于该回调的工作原理说明不足,无法找到解决思路,寻求帮助。

内容的提问来源于stack exchange,提问作者Codrut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 14:49:51