【问题标题】:How to render a scaled SVG to a QImage?如何将缩放的 SVG 渲染为 QImage?
【发布时间】:2012-01-23 00:20:27
【问题描述】:

QtSvg 模块中有一个QSvgRenderer 类,可以将图像渲染到QPaintDevice。这个可以是QImage。在这种情况下,我们将创建:

Image svgBufferImage(renderer.defaultSize(), QImage::Format_ARGB32);

但是如何从 SVG 渲染器渲染到与默认大小不同的 QImage?既然 SVG 格式的图像可以在不损失质量的情况下进行缩放,那么是否可以使用QSvgRenderer 从 SVG 文件生成静态图像,例如 PNG?

有人有更好的主意吗?基本上我需要从不同大小的 SVG 文件创建像 PNG 这样的图像。

【问题讨论】:

    标签: image qt svg


    【解决方案1】:

    只需为您的QImage 提供所需的大小。 SVG 渲染器将缩放以适应整个图像。

    #include <QApplication>
    #include <QSvgRenderer>
    #include <QPainter>
    #include <QImage>
    
    // In your .pro file:
    // QT += svg 
    
    int main(int argc, char **argv)
    {
        // A QApplication instance is necessary if fonts are used in the SVG
        QApplication app(argc, argv);
    
        // Load your SVG
        QSvgRenderer renderer(QString("./svg-logo-h.svg"));
    
        // Prepare a QImage with desired characteritisc
        QImage image(500, 200, QImage::Format_ARGB32);
        image.fill(0xaaA08080);  // partly transparent red-ish background
    
        // Get QPainter that paints to the image
        QPainter painter(&image);
        renderer.render(&painter);
    
        // Save, image format based on file extension
        image.save("./svg-logo-h.png");
    }
    

    这将从传入的 SVG 文件创建一个 500x200 的 PNG 图像。

    带有来自SVG logos 页面的 SVG 图像的示例输出:

    【讨论】:

    • 查看这个以获得更简单的解决方案stackoverflow.com/questions/10079011/qpixmap-and-svg/…
    • @Yash:更简单,但这里的问题特别要求缩放。 (即使是这样,上面的答案也比必要的要复杂一些,但演示了您可能需要/想要的其他东西。)
    • @Mat 是的。但是 SVG 不受任何尺寸限制,因此使用提供 QSize 的 pixmap 方法,它可以根据需要进行缩放。您可以从像素图创建 QIMage。
    • @V.K.:这确实会随着测试的 SVG 放大/缩小。如果您有上述代码无法缩放 SVG 的示例,请分享。你的另一个问题是还有很多事情要做。
    【解决方案2】:

    这里是完整的答案:

    QImage QPixmap::toImage() 
    

    如果像素图有 1 位深度,则返回的图像也将是 1 位深度。具有更多位的图像将以紧密代表底层系统的格式返回。通常这将是 QImage::Format_ARGB32_Premultiplied 用于具有 alpha 的像素图和 QImage::Format_RGB32 或 QImage::Format_RGB16 用于不带 alpha 的像素图。

    QImage img = QIcon("filepath.svg").pixmap(QSize(requiredsize)).toImage()
    

    也复制上面的答案

    // Save, image format based on file extension
    image.save("./svg-logo-h.png");
    

    【讨论】:

    • pixmap() 可能会返回与requiredsize 不同的大小,这使得该解决方案有些不切实际。
    【解决方案3】:

    如果您有简单的 svg,例如图标或小图像,例如用于替换颜色,最好使用 NanoSVG lib

    它有 Qt 包装器,由我编码 Qt Svg Render

    非常小,只有2个header和1个cpp。

    用法:

    QString svgPath="your svg Path";
      QString pngPath="path for png";
      QSize imageSize(your image Path size);
      const QSize resultSize(size that you want to get);
      QImage image(sizeW, sizeH, Format);//End of param
      
      QFile svgFile(svgPath);
      if (svgFile.open(QIODevice::ReadOnly))
      {
          int svgFileSize=svgFile.size();
          QByteArray ba;
          ba.resize(svgFileSize + 1);
          svgFile.read(ba.data(), svgFileSize);
          ba.back() = {};
          if (auto const nsi(nsvgParse(ba.data(), "px", 96)); nsi)
          {
              image.fill(Qt::transparent);
              QPainter p(&image);
              p.setRenderHint(QPainter::Antialiasing, true);
    
              drawSVGImage(&p, nsi, resultSize.width(), resultSize.height());
    
              nsvgDelete(nsi);
              image.save(pngPath);// if you want to save image
          }
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-19
      • 1970-01-01
      • 2013-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多