peekPixels usage in Hello World app

144 views
Skip to first unread message

Hong Zhang

unread,
Oct 6, 2023, 2:51:49 PM10/6/23
to skia-discuss
Hi channel,

I want to get started on Skia programming. This is basically a HelloWorld implementation trying to save an image as a jpeg. This code was compiled fine, but broke at  SkAssertResult(canvas.peekPixels(&pixmap));. peekPixels function is failing. What is the problem with the peekPixels usage?

#include "include/core/SkCanvas.h"
#include "include/core/SkSurface.h"
#include "include/core/SkImage.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkData.h"
#include "include/core/SkStream.h"
#include "include/encode/SkPngEncoder.h"
#include "include/encode/SkJpegEncoder.h"

constexpr static int multiplier = 5;
int main() {
  // Create a new Skia canvas.
  SkCanvas canvas(33 * multiplier, 48 * multiplier);

  canvas.drawColor(SK_ColorWHITE);
  SkPaint paint;
  paint.setColor(SK_ColorBLUE);
  canvas.drawCircle(64, 64, 64, paint);

 
  // Create a new SkBitmap to store the generated JPEG image.
//   SkBitmap bitmap;

  SkPixmap pixmap;
//   SkAssertResult(bitmap.peekPixels(&pixmap));

  SkAssertResult(canvas.peekPixels(&pixmap));

  SkFILEWStream stream("test.jpg");
  SkJpegEncoder::Options options;
  options.fQuality = 90;

  auto ret = SkJpegEncoder::Encode(&stream, pixmap, options);

  if (ret) {
    printf("success\n");
  } else {
    printf("fail\n");
  }


  return 0;
}

Brian Osman

unread,
Oct 6, 2023, 2:56:12 PM10/6/23
to skia-d...@googlegroups.com
The canvas you're creating doesn't actually have any pixels attached to it, at all. Creating one with this constructor:

    SkCanvas canvas(33 * multiplier, 48 * multiplier);

... just creates a blank canvas that doesn't do anything. (I don't even know why we have that constructor, actually!) Instead, you should create an SkSurface (with the dimensions you want), and then get the canvas from that surface:

    sk_sp<SkSurface> surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(width, height));
    SkCanvas* canvas = surface->getCanvas();

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/skia-discuss/dd051669-6090-4265-92eb-c631ae9f0a87n%40googlegroups.com.

Hong

unread,
Oct 8, 2023, 9:08:58 AM10/8/23
to skia-d...@googlegroups.com

Thanks Brian for the advice. I now constructed the SkSurface, but it hits segment fault on canvas->drawColor line.
Basically the first several line I changed to,

onstexpr static int multiplier = 5;
int main() {

sk_sp<SkSurface> surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(33 * multiplier, 48 * multiplier));
SkCanvas* canvas = surface->getCanvas();
// Create a new Skia canvas.
//SkCanvas canvas(33 * multiplier, 48 * multiplier);

canvas->drawColor(SK_ColorWHITE);
SkPaint paint;
paint.setColor(SK_ColorBLUE);
canvas->drawCircle(64, 64, 64, paint);

The canvas->drawColor is hitting the segment fault. The stack trace looks like,

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x0000000000000000
    frame #1: 0x00000001000617cf my_project`SkCanvas::drawPaint(this=0x00000003075a32d8, paint=0x00000003075a2f28) at SkCanvas.cpp:1765:11
    frame #2: 0x000000010006776e my_project`SkCanvas::drawColor(this=0x00000003075a32d8, c=0x00000003075a2fb0, mode=kSrcOver) at SkCanvas.cpp:2701:11
    frame #3: 0x00000001000041cc my_project`SkCanvas::drawColor(this=0x00000003075a32d8, color=4294967295, mode=kSrcOver) at SkCanvas.h:1139:15
    frame #4: 0x0000000100003f09 my_project`main at main.cc:18:11
    frame #5: 0x00000002034aa41f dyld`start + 1903

Anything you find incorrect?

You received this message because you are subscribed to a topic in the Google Groups "skia-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/skia-discuss/YWDn0sHFGgE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to skia-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/skia-discuss/CAMcBjo67hgOejeyyfQ58n%2Bov8d-NXsFAuiYi2svB8CwxbQ8p-Q%40mail.gmail.com.

craste...@gmail.com

unread,
Oct 8, 2023, 11:58:42 PM10/8/23
to skia-discuss
Did you verify that the canvas pointer is not nullptr?

Hong Zhang

unread,
Oct 9, 2023, 12:46:22 PM10/9/23
to skia-discuss
yes the canvas pointer is not null (the stacktrace I shared also suggests this)
Also does anyone know where to find the sample code to make skia fiddle to work from end to end, i.e. create the canvas, run this function and save to a file? https://fiddle.skia.org/c/ad2eef98669b1efc61e36a9c4e8192e1

K. Moon

unread,
Oct 9, 2023, 1:03:32 PM10/9/23
to skia-d...@googlegroups.com
This code looks fine to me, and the stack trace doesn't make a lot of sense. Perhaps there's something wrong with your build? Have you tried starting over with a clean build?

Brian Osman

unread,
Oct 9, 2023, 1:04:32 PM10/9/23
to skia-d...@googlegroups.com
You may be encountering an issue with clang's "trivial" ABI. Skia disables this by default for "official" builds, but if you're doing a developer build, you could end up with a version of Skia that doesn't interact correctly with your own code. Try changing your GN arguments when you build Skia:

     gn gen out/Debug --args='is_trivial_abi=false'

Reply all
Reply to author
Forward
0 new messages