What is the recommended way to resize bitmaps?

2,385 views
Skip to first unread message

Matthew Leibowitz

unread,
Feb 16, 2017, 2:19:09 PM2/16/17
to skia-discuss
I am resizing bitmaps here, and I was just wondering what is the correct way to do this. There are several options:
  1. SkCanvas::drawBitmap() - this can't control quality, I think
  2. SkPixmap::scalePixels() - this looks promising
  3. SkBitmapScaler - this is "private" or "internal"
What is the correct option, and are they any better options?

Cary Clark

unread,
Feb 16, 2017, 2:42:46 PM2/16/17
to skia-d...@googlegroups.com
There are many options. We need to get rid of a few.

drawBitmap can control quality by providing a pointer to a paint, but Bitmaps are (one of) the redheaded step-children of Skia and may go away someday.
Your best choice is SkImage.

paint.setFilterQuality(kHigh_SkFIlterQualtiy);
canvas->drawImage(image.get(), 0, 0, &paint);

For more flexibility (e,g., to fill a path with an image) add an SkImageShader to a SkPaint.


--
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+unsubscribe@googlegroups.com.
To post to this group, send email to skia-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/skia-discuss.
For more options, visit https://groups.google.com/d/optout.

Mike Reed

unread,
Feb 16, 2017, 2:44:00 PM2/16/17
to skia-d...@googlegroups.com
+1 for using images.

Matthew Leibowitz

unread,
Feb 16, 2017, 2:56:31 PM2/16/17
to skia-discuss
What If I want to load an image, resize and then save? All in memory and without drawing.
I don't really want to draw onto a canvas just yet - rather resize and use them later.

On Thursday, February 16, 2017 at 9:42:46 PM UTC+2, Cary Clark wrote:
There are many options. We need to get rid of a few.

drawBitmap can control quality by providing a pointer to a paint, but Bitmaps are (one of) the redheaded step-children of Skia and may go away someday.
Your best choice is SkImage.

paint.setFilterQuality(kHigh_SkFIlterQualtiy);
canvas->drawImage(image.get(), 0, 0, &paint);

For more flexibility (e,g., to fill a path with an image) add an SkImageShader to a SkPaint.

On Thu, Feb 16, 2017 at 2:19 PM, Matthew Leibowitz <mattl...@live.com> wrote:
I am resizing bitmaps here, and I was just wondering what is the correct way to do this. There are several options:
  1. SkCanvas::drawBitmap() - this can't control quality, I think
  2. SkPixmap::scalePixels() - this looks promising
  3. SkBitmapScaler - this is "private" or "internal"
What is the correct option, and are they any better options?

--
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.

Cary Clark

unread,
Feb 16, 2017, 3:04:14 PM2/16/17
to skia-d...@googlegroups.com
Then you'll want to draw an image onto a surface, then save the surface.

To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss+unsubscribe@googlegroups.com.

Mike Reed

unread,
Feb 16, 2017, 3:12:29 PM2/16/17
to skia-d...@googlegroups.com
Drawing (with a resize) is no more work than resizing, since you have to "resize" into another buffer.

SkImage a = ...
SkSurface surf = 
surf->getCanvas()->drawImage(a, ...)
SkImage b = surf->makeImageSnapshot()
// now you can draw b, or encode it back to png, etc.

To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss+unsubscribe@googlegroups.com.

Matthew Leibowitz

unread,
Feb 16, 2017, 7:36:04 PM2/16/17
to skia-discuss
I was just about to do things, and then I noticed another resize method :)
  • SkImage::scalePixels
This appears to do stuff and then call SkPixmap::scalePixels...

The real reason for asking is that I am working on creating SkiaSharp - a .NET binding around skia. But, I am unsure now what is "safe" to make public. 

Also, I am wanting the lowest overhead fore resizing. Isn't creating a surface, canvas, drawing, and then creating a snapshot quite a bit of overhead to just perform a scale algorithm from one pixel buffer into another? Also, will the makeImageSnapshot create another copy of the pixels in memory? So, at the end of the day I will have 3 images in memory instead of 2?

Cary Clark

unread,
Feb 17, 2017, 7:20:19 AM2/17/17
to skia-d...@googlegroups.com
Matthew

There's no real overhead in creating the pieces. All of the time is spent scaling the pixels.

Both SkBitmap and SkPixmap are slowly headed towards the chopping block.
SkImage is intended to be source only and SkSurface is destination only.
Internally, a lot of optimizations take advantage of this restriction.

If you profile the SkImage / SkSurface approach and discover that there is measurable overhead, then that is a performance bug.

Feel free to file any bugs you come across at skbug.com

Thanks
Cary



To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss+unsubscribe@googlegroups.com.

Mike Reed

unread,
Feb 17, 2017, 7:37:45 AM2/17/17
to skia-d...@googlegroups.com
scalePixels should be fine if you always want the result to be a raster (cpu), but it is not as useful if you intend to draw the result and the original was on the gpu. Hence the draw-into-a-surface pattern (which preserves gpu-ness if the original was on the gpu).

makeImageSnapshot does not create a 3rd buffer, assuming you destroy the surface and don't draw into it again.

We are experimenting with a scaleImage call right now, but it is not yet released to the public API. It is similar to scalePixels, but will return a new image, allowing it to preserve gpu-ness, as the draw/surface pattern does.

Hal Canary

unread,
Feb 17, 2017, 8:34:56 AM2/17/17
to skia-discuss
On Fri, Feb 17, 2017 at 7:20 AM, 'Cary Clark' via skia-discuss <skia-d...@googlegroups.com> wrote:
Both SkBitmap and SkPixmap are slowly headed towards the chopping block.

I'm not so sure about SkPixmap.  It is almost POD (the exception is a fInfo.fColorSpacem which is a sk_sp<T>) and is too useful as an API escape valve down to raw memory for the CPU backend.  For example: SkImage::MakeRasterCopy(), SkImage::MakeFromRaster(), SkImage::readPixels(), SkEncodeImage(), and potentially SkSurface::MakeRasterDirect().

Reply all
Reply to author
Forward
0 new messages