SVG images (image href) won't draw

49 views
Skip to first unread message

Ionut Cosmin Mihai

unread,
Jun 22, 2024, 3:04:28 PMJun 22
to skia-discuss
When drawing a SVG, the <image href...> is completely ignored although other viewers(Mozilla Firefox) can draw it.

Are there known limitations regarding the drawing of images in a svg file?

I'm trying to convert a svg to a png file.

This is how the code looks like :
sk_sp<SkData> read_file(const char *path)
{
  std::ifstream file(path, std::ios::binary);
  file.seekg(0, std::ios::end);
  size_t size = file.tellg();
  file.seekg(0, std::ios::beg);

  sk_sp<SkData> data = SkData::MakeUninitialized(size);
  file.read((char *)data->writable_data(), size);
  return data;
}

void DrawingService::renderSVG(Path svgPath, Path outputPath,
                               cv::Size imageSize)
{
  sk_sp<SkData> svgData = read_file(svgPath.string().c_str());

  SkMemoryStream  stream(svgData);
  sk_sp<SkSVGDOM> svgDOM = SkSVGDOM::MakeFromStream(stream);

  if (!svgDOM) {
    fprintf(stderr, "Failed to load SVG file\n");
    return;
  }

  // Create a surface to render the SVG
  SkImageInfo info =
      SkImageInfo::MakeN32Premul(imageSize.width, imageSize.height);

  auto surface = SkSurfaces::Raster(info);

  if (!surface) {
    fprintf(stderr, "Failed to create surface\n");
    return;
  }

  SkCanvas *canvas = surface->getCanvas();
  canvas->clear(SK_ColorWHITE);

  // Scale the SVG to fit the surface
  SkRect bounds = SkRect::MakeIWH(imageSize.width, imageSize.height);
  float  scaleX = imageSize.width / bounds.width();
  float  scaleY = imageSize.height / bounds.height();
  float  scale = std::min(scaleX, scaleY);

  canvas->scale(scaleX, scaleY);
  svgDOM->setContainerSize(
      SkSize::Make(bounds.width() * scale, bounds.height() * scale));

  // Render the SVG
  svgDOM->render(canvas);

  // Encode the surface to PNG
  SkPixmap       pixmap;
  sk_sp<SkImage> image = surface->makeImageSnapshot();

  image->peekPixels(&pixmap);
  std::vector<std::vector<SkColor>> colors;

  SkFILEWStream         outFile(outputPath.string().c_str());
  SkPngEncoder::Options options;

  SkPngEncoder::Encode(&outFile, pixmap, options);
  outFile.flush();
}

Данил Буланов

unread,
Jun 22, 2024, 3:21:12 PMJun 22
to skia-discuss
If I got you right, in order to draw images (or other things wich require some external resource) you need to specify a resource prociver for that. For instance, if your images have href=base64, then you can use skresources::DataURIResourceProviderProxy, you can also have a look at SvgSlide.cpp, there is an example which uses different resource provider (dont forget to register the codecs, as it it listed in the comments to resourece providers)

суббота, 22 июня 2024 г. в 22:04:28 UTC+3, ionut.cos...@gmail.com:

Данил Буланов

unread,
Jun 22, 2024, 3:25:04 PMJun 22
to skia-discuss
In the first case I meant taht you can use skresources::DataURIResourceProviderProxy without resource provider and font manager, just with ImageDecodeStrategy

суббота, 22 июня 2024 г. в 22:21:12 UTC+3, Данил Буланов:
Reply all
Reply to author
Forward
0 new messages