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

STM32MP1中cairo_surface_write_to_png持续返回CAIRO_STATUS_WRITE_ERROR

解决Cairo写入PNG触发CAIRO_STATUS_WRITE_ERROR的问题

你的代码里有个致命错误:误用了mkdtemp函数。

mkdtemp的作用是创建临时目录,它要求模板字符串的末尾必须是6个连续的X,而且返回的是目录路径。你现在用的模板是./fileXXXXXX.png,不符合函数要求,最终生成的是一个目录而非文件。当你把目录路径传给cairo_surface_write_to_png时,它尝试往目录里写入文件,自然会触发写入错误。

修正方案

方案1:用mkstemp创建临时文件(推荐)

mkstemp是专门创建临时文件的函数,它会自动替换模板里的6个X为随机字符,创建并打开文件后返回文件描述符。修正后的代码如下:

if(pFile)
{
    char template[] = "./fileXXXXXX.png";
    // 创建临时文件,返回文件描述符
    int fd = mkstemp(template);
    if(fd != -1)
    {
        close(fd); // 先关闭文件,cairo会重新打开写入
        cairo_errCode = cairo_surface_write_to_png(image_surface, template);
        if(cairo_errCode == CAIRO_STATUS_SUCCESS)
        {
            // 这里写成功后的逻辑
        }
        // 用完临时文件后可以删除
        unlink(template);
    }
}

方案2:用mkdtemp创建目录后再生成文件名

如果你一定要用mkdtemp创建临时目录,需要在目录下拼接合法的文件名,再传给cairo:

if(pFile)
{
    char template[] = "./tempdirXXXXXX"; // 模板末尾是6个X,不带文件后缀
    char *tempDir = mkdtemp(template);
    if(tempDir)
    {
        char tempFileName[256];
        // 在临时目录下生成文件名
        snprintf(tempFileName, sizeof(tempFileName), "%s/output.png", tempDir);
        cairo_errCode = cairo_surface_write_to_png(image_surface, tempFileName);
        if(cairo_errCode == CAIRO_STATUS_SUCCESS)
        {
            // 成功后的逻辑
        }
        // 清理资源:删除文件和临时目录
        unlink(tempFileName);
        rmdir(tempDir);
    }
}

额外排查点

  • 检查image_surface的状态:调用cairo_surface_status(image_surface)确认surface是否创建成功,如果surface本身有错误,也会导致写入失败。
  • 验证pBitmap->mainSurface的有效性:确保这个surface没有错误状态,否则cairo_paint可能无法正确绘制内容,间接影响写入。
  • 检查路径长度:如果拼接后的文件名超过系统的PATH_MAX限制,也会触发写入错误,可以用snprintf确保路径不会溢出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 08:00:37