skia2/docs/SkImage_Reference.bmh
Brian Osman 410b302fb7 Update color space API in examples
Bug: skia:
Change-Id: I2304a7265ebae8dc67f9ddf3f94aa7c4d5eb2e26
Reviewed-on: https://skia-review.googlesource.com/c/187388
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2019-01-28 21:09:46 +00:00

1790 lines
57 KiB
Plaintext

#Topic Image
#Alias Image_Reference ##
#Class SkImage
#Code
#Populate
##
Image describes a two dimensional array of pixels to draw. The pixels may be
decoded in a Raster_Bitmap, encoded in a Picture or compressed data stream,
or located in GPU memory as a GPU_Texture.
Image cannot be modified after it is created. Image may allocate additional
storage as needed; for instance, an encoded Image may decode when drawn.
Image width and height are greater than zero. Creating an Image with zero width
or height returns Image equal to nullptr.
Image may be created from Bitmap, Pixmap, Surface, Picture, encoded streams,
GPU_Texture, YUV_ColorSpace data, or hardware buffer. Encoded streams supported
include BMP, GIF, HEIF, ICO, JPEG, PNG, WBMP, WebP. Supported encoding details
vary with platform.
#Subtopic Raster_Image
#Alias Raster_Image ##
#Line # pixels decoded in Raster_Bitmap ##
Raster_Image pixels are decoded in a Raster_Bitmap. These pixels may be read
directly and in most cases written to, although edited pixels may not be drawn
if Image has been copied internally.
##
#Subtopic Texture_Image
#Line # pixels located on GPU ##
Texture_Image are located on GPU and pixels are not accessible. Texture_Image
are allocated optimally for best performance. Raster_Image may
be drawn to GPU_Surface, but pixels are uploaded from CPU to GPU downgrading
performance.
##
#Subtopic Lazy_Image
#Line # deferred pixel buffer ##
Lazy_Image defer allocating buffer for Image pixels and decoding stream until
Image is drawn. Lazy_Image caches result if possible to speed up repeated
drawing.
##
# ------------------------------------------------------------------------------
#Method static sk_sp<SkImage> MakeRasterCopy(const SkPixmap& pixmap)
#In Constructors
#Line # creates Image from Pixmap and copied pixels ##
#Populate
#Example
#Height 50
#Description
Draw a five by five bitmap, and draw a copy in an Image. Editing the pixmap
alters the bitmap draw, but does not alter the Image draw since the Image
contains a copy of the pixels.
##
uint8_t storage[][5] = {{ 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 },
{ 0xAC, 0xA8, 0x89, 0xA7, 0x87 },
{ 0x9B, 0xB5, 0xE5, 0x95, 0x46 },
{ 0x90, 0x81, 0xC5, 0x71, 0x33 },
{ 0x75, 0x55, 0x44, 0x40, 0x30 }};
SkImageInfo imageInfo = SkImageInfo::Make(5, 5, kGray_8_SkColorType, kOpaque_SkAlphaType);
SkPixmap pixmap(imageInfo, storage[0], sizeof(storage) / 5);
SkBitmap bitmap;
bitmap.installPixels(pixmap);
sk_sp<SkImage> image = SkImage::MakeRasterCopy(pixmap);
*pixmap.writable_addr8(2, 2) = 0x00;
canvas->scale(10, 10);
canvas->drawBitmap(bitmap, 0, 0);
canvas->drawImage(image, 10, 0);
##
#SeeAlso MakeRasterData MakeFromGenerator
#Method ##
# ------------------------------------------------------------------------------
#Method static sk_sp<SkImage> MakeRasterData(const SkImageInfo& info, sk_sp<SkData> pixels, size_t rowBytes)
#In Constructors
#Line # creates Image from Image_Info and shared pixels ##
#Populate
#Example
#Image 3
size_t rowBytes = image->width() * SkColorTypeBytesPerPixel(kRGBA_8888_SkColorType);
sk_sp<SkData> data = SkData::MakeUninitialized(rowBytes * image->height());
SkImageInfo dstInfo = SkImageInfo::MakeN32(image->width(), image->height(),
kPremul_SkAlphaType);
image->readPixels(dstInfo, data->writable_data(), rowBytes, 0, 0, SkImage::kAllow_CachingHint);
sk_sp<SkImage> raw = SkImage::MakeRasterData(dstInfo.makeColorType(kRGBA_8888_SkColorType),
data, rowBytes);
canvas->drawImage(image, 0, 0);
canvas->drawImage(raw.get(), 128, 0);
##
#SeeAlso MakeRasterCopy MakeFromGenerator
#Method ##
# ------------------------------------------------------------------------------
#Typedef void* ReleaseContext
#Line # parameter type for MakeFromRaster ##
#Code
#Populate
##
Caller data passed to RasterReleaseProc; may be nullptr.
#SeeAlso MakeFromRaster RasterReleaseProc
##
#Typedef void (*RasterReleaseProc)(const void* pixels, ReleaseContext)
#Line # parameter type for MakeFromRaster ##
#Code
#Populate
##
Function called when Image no longer shares pixels. ReleaseContext is
provided by caller when Image is created, and may be nullptr.
#SeeAlso ReleaseContext MakeFromRaster
##
#Method static sk_sp<SkImage> MakeFromRaster(const SkPixmap& pixmap,
RasterReleaseProc rasterReleaseProc,
ReleaseContext releaseContext)
#In Constructors
#Line # creates Image from Pixmap, with release ##
#Populate
#Example
#Function
static void releaseProc(const void* pixels, SkImage::ReleaseContext context) {
int* countPtr = static_cast<int*>(context);
*countPtr += 1;
}
##
void draw(SkCanvas* canvas) {
SkColor color = 0;
SkPixmap pixmap(SkImageInfo::MakeN32(1, 1, kPremul_SkAlphaType), &color, 4);
int releaseCount = 0;
sk_sp<SkImage> image(SkImage::MakeFromRaster(pixmap, releaseProc, &releaseCount));
SkDebugf("before reset: %d\n", releaseCount);
image.reset();
SkDebugf("after reset: %d\n", releaseCount);
}
#StdOut
before reset: 0
after reset: 1
##
##
#SeeAlso MakeRasterCopy MakeRasterData MakeFromGenerator RasterReleaseProc ReleaseContext
#Method ##
# ------------------------------------------------------------------------------
#Method static sk_sp<SkImage> MakeFromBitmap(const SkBitmap& bitmap)
#In Constructors
#Line # creates Image from Bitmap, sharing or copying pixels ##
#Populate
#Example
#Description
The first Bitmap is shared; writing to the pixel memory changes the first
Image.
The second Bitmap is marked immutable, and is copied; writing to the pixel
memory does not alter the second Image.
##
#Height 50
uint8_t storage[][5] = {{ 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 },
{ 0xAC, 0xA8, 0x89, 0xA7, 0x87 },
{ 0x9B, 0xB5, 0xE5, 0x95, 0x46 },
{ 0x90, 0x81, 0xC5, 0x71, 0x33 },
{ 0x75, 0x55, 0x44, 0x40, 0x30 }};
SkImageInfo imageInfo = SkImageInfo::Make(5, 5, kGray_8_SkColorType, kOpaque_SkAlphaType);
SkPixmap pixmap(imageInfo, storage[0], sizeof(storage) / 5);
SkBitmap bitmap;
bitmap.installPixels(pixmap);
sk_sp<SkImage> image1 = SkImage::MakeFromBitmap(bitmap);
bitmap.setImmutable();
sk_sp<SkImage> image2 = SkImage::MakeFromBitmap(bitmap);
*pixmap.writable_addr8(2, 2) = 0x00;
canvas->scale(10, 10);
canvas->drawImage(image1, 0, 0);
canvas->drawImage(image2, 10, 0);
##
#SeeAlso MakeFromRaster MakeRasterCopy MakeFromGenerator MakeRasterData
#Method ##
# ------------------------------------------------------------------------------
#Method static sk_sp<SkImage> MakeFromGenerator(std::unique_ptr<SkImageGenerator> imageGenerator,
const SkIRect* subset = nullptr)
#In Constructors
#Line # creates Image from a stream of data ##
#Populate
#Example
#Height 128
#Description
The generator returning Picture cannot be shared; std::move transfers ownership to generated Image.
##
SkPictureRecorder recorder;
recorder.beginRecording(100, 100)->drawColor(SK_ColorRED);
auto picture = recorder.finishRecordingAsPicture();
auto gen = SkImageGenerator::MakeFromPicture({100, 100}, picture, nullptr, nullptr,
SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB());
sk_sp<SkImage> image = SkImage::MakeFromGenerator(std::move(gen));
canvas->drawImage(image, 0, 0);
##
#SeeAlso MakeFromEncoded
#Method ##
# ------------------------------------------------------------------------------
#Method static sk_sp<SkImage> MakeFromEncoded(sk_sp<SkData> encoded, const SkIRect* subset = nullptr)
#In Constructors
#Line # creates Image from encoded data ##
#Populate
#Example
#Image 3
int x = 0;
for (int quality : { 100, 50, 10, 1} ) {
sk_sp<SkData> encodedData = image->encodeToData(SkEncodedImageFormat::kJPEG, quality);
sk_sp<SkImage> image = SkImage::MakeFromEncoded(encodedData);
canvas->drawImage(image, x, 0);
x += 64;
}
##
#SeeAlso MakeFromGenerator
#Method ##
# ------------------------------------------------------------------------------
#Enum CompressionType
#Line # option for MakeFromCompressed ##
#Code
#Populate
##
Used to inform MakeFromCompressed which compression method was used on the
input data.
#Const kETC1_CompressionType 0
#Line # compressed data uses ETC1 compression ##
##
#NoExample
##
#SeeAlso MakeFromCompressed
#Enum ##
#Method static sk_sp<SkImage> MakeFromCompressed(GrContext* context, sk_sp<SkData> data, int width, int height, CompressionType type)
#In Constructors
#Line # creates a GPU-backed Image from compressed data ##
#Populate
#NoExample
##
#SeeAlso MakeFromTexture CompressionType
#Method ##
# ------------------------------------------------------------------------------
#Typedef void (*TextureReleaseProc)(ReleaseContext releaseContext)
#Line # parameter type for MakeFromTexture ##
#Code
#Populate
##
User function called when supplied texture may be deleted.
#SeeAlso MakeFromTexture
##
#Method static sk_sp<SkImage> MakeFromTexture(GrContext* context,
const GrBackendTexture& backendTexture,
GrSurfaceOrigin origin,
SkColorType colorType,
SkAlphaType alphaType,
sk_sp<SkColorSpace> colorSpace)
#In Constructors
#Line # creates Image from GPU_Texture ##
#Populate
#Example
#Image 3
#Platform gpu
#Height 128
#Description
A back-end texture has been created and uploaded to the GPU outside of this example.
##
GrContext* context = canvas->getGrContext();
if (!context) {
return;
}
canvas->scale(.25f, .25f);
int x = 0;
for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin } ) {
sk_sp<SkImage> image = SkImage::MakeFromTexture(context, backEndTexture,
origin, kRGBA_8888_SkColorType, kOpaque_SkAlphaType, nullptr);
canvas->drawImage(image, x, 0);
x += 512;
}
##
#SeeAlso MakeFromAdoptedTexture SkSurface::MakeFromBackendTexture
#Method ##
# ------------------------------------------------------------------------------
#Method static sk_sp<SkImage> MakeFromTexture(GrContext* context,
const GrBackendTexture& backendTexture,
GrSurfaceOrigin origin,
SkColorType colorType,
SkAlphaType alphaType,
sk_sp<SkColorSpace> colorSpace,
TextureReleaseProc textureReleaseProc,
ReleaseContext releaseContext)
#Populate
#Example
#Description
textureReleaseProc may be called at some later point in time. In this example,
textureReleaseProc has no effect on the drawing.
##
#Platform gpu
#Image 4
GrContext* context = canvas->getGrContext();
if (!context) {
return;
}
auto debugster = [](SkImage::ReleaseContext releaseContext) -> void {
*((int *) releaseContext) += 128;
};
int x = 0, y = 0;
for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin } ) {
sk_sp<SkImage> image = SkImage::MakeFromTexture(context, backEndTexture,
origin, kRGBA_8888_SkColorType, kOpaque_SkAlphaType, nullptr, debugster, &x);
canvas->drawImage(image, x, y);
y += 128;
}
##
#SeeAlso MakeFromAdoptedTexture SkSurface::MakeFromBackendTexture
#Method ##
# ------------------------------------------------------------------------------
#Method static sk_sp<SkImage> MakeCrossContextFromEncoded(GrContext* context, sk_sp<SkData> data,
bool buildMips,
SkColorSpace* dstColorSpace,
bool limitToMaxTextureSize = false)
#In Constructors
#Line # creates Image from encoded data, and uploads to GPU ##
#Populate
#Example
#Image 4
#Height 64
GrContext* context = canvas->getGrContext();
sk_sp<SkData> encodedData = image->encodeToData(SkEncodedImageFormat::kJPEG, 100);
sk_sp<SkImage> image = SkImage::MakeCrossContextFromEncoded(context,
encodedData, false, nullptr);
canvas->drawImage(image, 0, 0);
##
#SeeAlso MakeCrossContextFromPixmap
#Method ##
# ------------------------------------------------------------------------------
#Method static sk_sp<SkImage> MakeCrossContextFromPixmap(GrContext* context, const SkPixmap& pixmap,
bool buildMips,
SkColorSpace* dstColorSpace,
bool limitToMaxTextureSize = false)
#In Constructors
#Line # creates Image from Pixmap, and uploads to GPU ##
#Populate
#Example
#Image 4
#Height 64
GrContext* context = canvas->getGrContext();
SkPixmap pixmap;
if (source.peekPixels(&pixmap)) {
sk_sp<SkImage> image = SkImage::MakeCrossContextFromPixmap(context, pixmap,
false, nullptr);
canvas->drawImage(image, 0, 0);
}
##
#SeeAlso MakeCrossContextFromEncoded
#Method ##
# ------------------------------------------------------------------------------
#Method static sk_sp<SkImage> MakeFromAdoptedTexture(GrContext* context,
const GrBackendTexture& backendTexture,
GrSurfaceOrigin surfaceOrigin,
SkColorType colorType,
SkAlphaType alphaType = kPremul_SkAlphaType,
sk_sp<SkColorSpace> colorSpace = nullptr)
#In Constructors
#Line # creates Image from GPU_Texture, managed internally ##
#Populate
#Example
#Image 5
#Platform gpu
if (!canvas->getGrContext()) {
return;
}
canvas->scale(.5f, .5f);
canvas->clear(0x7f3f5f7f);
int x = 0, y = 0;
for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin } ) {
for (auto alpha : { kOpaque_SkAlphaType, kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
sk_sp<SkImage> image = SkImage::MakeFromAdoptedTexture(canvas->getGrContext(),
backEndTexture, origin,
kRGBA_8888_SkColorType, alpha);
canvas->drawImage(image, x, y);
x += 160;
}
x -= 160 * 3;
y += 256;
}
##
#SeeAlso MakeFromTexture MakeFromYUVTexturesCopy
#Method ##
# ------------------------------------------------------------------------------
#Method static sk_sp<SkImage> MakeFromYUVATexturesCopy(GrContext* context,
SkYUVColorSpace yuvColorSpace,
const GrBackendTexture yuvaTextures[],
const SkYUVAIndex yuvaIndices[4],
SkISize imageSize,
GrSurfaceOrigin imageOrigin,
sk_sp<SkColorSpace> imageColorSpace = nullptr)
#In Constructor
#Line # creates Image from YUV_ColorSpace data ##
#Populate
#NoExample
##
#SeeAlso MakeFromYUVATexturesCopyWithExternalBackend MakeFromYUVATextures
#Method ##
#Method static sk_sp<SkImage> MakeFromYUVATextures(GrContext* context,
SkYUVColorSpace yuvColorSpace,
const GrBackendTexture yuvaTextures[],
const SkYUVAIndex yuvaIndices[4],
SkISize imageSize,
GrSurfaceOrigin imageOrigin,
sk_sp<SkColorSpace> imageColorSpace = nullptr);
#In Constructor
#Line # creates Image from YUV_ColorSpace data ##
#Populate
#NoExample
##
#SeeAlso MakeFromYUVATexturesCopy MakeFromYUVATexturesCopyWithExternalBackend
#Method ##
#Method static sk_sp<SkImage> MakeFromYUVAPixmaps(
GrContext* context,
SkYUVColorSpace yuvColorSpace,
const SkPixmap yuvaPixmaps[],
const SkYUVAIndex yuvaIndices[4],
SkISize imageSize,
GrSurfaceOrigin imageOrigin,
bool buildMips,
bool limitToMaxTextureSize = false,
sk_sp<SkColorSpace> imageColorSpace = nullptr);
#In Constructor
#Line # creates Image from YUV_ColorSpace data ##
#Populate
#NoExample
##
#SeeAlso MakeFromYUVATextures
#Method ##
# ------------------------------------------------------------------------------
#Method static sk_sp<SkImage> MakeFromYUVATexturesCopyWithExternalBackend(
GrContext* context,
SkYUVColorSpace yuvColorSpace,
const GrBackendTexture yuvaTextures[],
const SkYUVAIndex yuvaIndices[4],
SkISize imageSize,
GrSurfaceOrigin imageOrigin,
const GrBackendTexture& backendTexture,
sk_sp<SkColorSpace> imageColorSpace = nullptr)
#In Constructor
#Line # creates Image from planar YUV_ColorSpace, stored in texture ##
#Populate
#NoExample
##
#SeeAlso MakeFromYUVATexturesCopy MakeFromYUVATextures
#Method ##
#Method static sk_sp<SkImage> MakeFromYUVTexturesCopy(GrContext* context, SkYUVColorSpace yuvColorSpace,
const GrBackendTexture yuvTextures[3],
GrSurfaceOrigin imageOrigin,
sk_sp<SkColorSpace> imageColorSpace = nullptr)
#In Constructors
#Line # creates Image from YUV_ColorSpace data in three planes ##
#Populate
#NoExample
##
#SeeAlso MakeFromYUVTexturesCopyWithExternalBackend MakeFromNV12TexturesCopy MakeFromYUVATexturesCopy
#Method ##
# ------------------------------------------------------------------------------
#Method static sk_sp<SkImage> MakeFromYUVTexturesCopyWithExternalBackend(
GrContext* context, SkYUVColorSpace yuvColorSpace,
const GrBackendTexture yuvTextures[3], GrSurfaceOrigin imageOrigin,
const GrBackendTexture& backendTexture, sk_sp<SkColorSpace> imageColorSpace = nullptr);
#In Constructors
#Line # creates Image from planar YUV_ColorSpace, stored in texture ##
#Populate
#NoExample
##
#SeeAlso MakeFromYUVTexturesCopy MakeFromNV12TexturesCopy MakeFromYUVATexturesCopyWithExternalBackend
#Method ##
# ------------------------------------------------------------------------------
#Method static sk_sp<SkImage> MakeFromNV12TexturesCopy(GrContext* context,
SkYUVColorSpace yuvColorSpace,
const GrBackendTexture nv12Textures[2],
GrSurfaceOrigin imageOrigin,
sk_sp<SkColorSpace> imageColorSpace = nullptr)
#In Constructors
#Line # creates Image from YUV_ColorSpace data in three planes ##
#Populate
#NoExample
##
#SeeAlso MakeFromNV12TexturesCopyWithExternalBackend MakeFromYUVTexturesCopy MakeFromYUVATexturesCopy
#Method ##
#Method static sk_sp<SkImage> MakeFromNV12TexturesCopyWithExternalBackend(
GrContext* context,
SkYUVColorSpace yuvColorSpace,
const GrBackendTexture nv12Textures[2],
GrSurfaceOrigin imageOrigin,
const GrBackendTexture& backendTexture,
sk_sp<SkColorSpace> imageColorSpace = nullptr);
#In Constructors
#Line # creates Image from planar YUV_ColorSpace, stored in texture ##
#Populate
#NoExample
##
#SeeAlso MakeFromNV12TexturesCopy MakeFromYUVTexturesCopy MakeFromYUVATexturesCopyWithExternalBackend
#Method ##
# ------------------------------------------------------------------------------
# currently uncalled by any test or client ##
#Bug 7424
#EnumClass BitDepth
#Line # options for MakeFromPicture ##
#Code
#Populate
##
#Const kU8 0
#Line # uses 8-bit unsigned int per Color component ##
Use 8 bits per ARGB component using unsigned integer format.
##
#Const kF16 1
#Line # uses 16-bit float per Color component ##
Use 16 bits per ARGB component using half-precision floating point format.
##
#NoExample
##
#SeeAlso MakeFromPicture
#EnumClass ##
# ------------------------------------------------------------------------------
#Method static sk_sp<SkImage> MakeFromPicture(sk_sp<SkPicture> picture, const SkISize& dimensions,
const SkMatrix* matrix, const SkPaint* paint,
BitDepth bitDepth,
sk_sp<SkColorSpace> colorSpace)
#In Constructors
#Line # creates Image from Picture ##
#Populate
#Example
SkPaint paint;
SkPictureRecorder recorder;
SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
paint.setColor(color);
recordingCanvas->drawRect({10, 10, 30, 40}, paint);
recordingCanvas->translate(10, 10);
recordingCanvas->scale(1.2f, 1.4f);
}
sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
int x = 0, y = 0;
for (auto alpha : { 70, 140, 210 } ) {
paint.setAlpha(alpha);
auto srgbColorSpace = SkColorSpace::MakeSRGB();
sk_sp<SkImage> image = SkImage::MakeFromPicture(playback, {50, 50}, nullptr, &paint,
SkImage::BitDepth::kU8, srgbColorSpace);
canvas->drawImage(image, x, y);
x += 70; y += 70;
}
##
#SeeAlso SkCanvas::drawPicture
#Method ##
# ------------------------------------------------------------------------------
#Method static sk_sp<SkImage> MakeFromAHardwareBuffer(
AHardwareBuffer* hardwareBuffer,
SkAlphaType alphaType = kPremul_SkAlphaType,
sk_sp<SkColorSpace> colorSpace = nullptr,
GrSurfaceOrigin surfaceOrigin = kTopLeft_GrSurfaceOrigin)
#In Constructors
#Line # creates Image from Android hardware buffer ##
#Populate
#NoExample
##
#SeeAlso MakeFromRaster
#Method ##
# ------------------------------------------------------------------------------
#Subtopic Property
#Line # values and attributes ##
##
#Method int width() const
#In Property
#Line # returns pixel column count ##
#Populate
#Example
#Image 4
#Height 96
canvas->translate(10, 10);
canvas->drawImage(image, 0, 0);
canvas->translate(0, image->height());
SkPaint paint;
canvas->drawLine(0, 10, image->width(), 10, paint);
canvas->drawString("width", image->width() / 2 - 15, 25, paint);
##
#SeeAlso dimensions() height()
#Method ##
# ------------------------------------------------------------------------------
#Method int height() const
#In Property
#Line # returns pixel row count ##
#Populate
#Example
#Image 4
#Height 96
canvas->translate(10, 10);
canvas->drawImage(image, 0, 0);
canvas->translate(image->width(), 0);
SkPaint paint;
canvas->drawLine(10, 0, 10, image->height(), paint);
canvas->drawString("height", 34, image->height() / 2, paint);
##
#SeeAlso dimensions() width()
#Method ##
# ------------------------------------------------------------------------------
#Method SkISize dimensions() const
#In Property
#Line # returns width() and height() ##
#Populate
#Example
#Image 4
SkISize dimensions = image->dimensions();
SkIRect bounds = image->bounds();
SkIRect dimensionsAsBounds = SkIRect::MakeSize(dimensions);
SkDebugf("dimensionsAsBounds %c= bounds\n", dimensionsAsBounds == bounds ? '=' : '!');
#StdOut
dimensionsAsBounds == bounds
##
##
#SeeAlso height() width() bounds()
#Method ##
# ------------------------------------------------------------------------------
#Method SkIRect bounds() const
#In Property
#Line # returns width() and height() as Rectangle ##
#Populate
#Example
#Height 128
#Image 4
SkIRect bounds = image->bounds();
for (int x : { 0, bounds.width() } ) {
for (int y : { 0, bounds.height() } ) {
canvas->drawImage(image, x, y);
}
}
##
#SeeAlso dimensions()
#Method ##
# ------------------------------------------------------------------------------
#Method uint32_t uniqueID() const
#In Property
#Line # returns identifier for Image ##
#Populate
#Example
#Image 5
#Height 156
sk_sp<SkImage> subset = image->makeSubset({10, 20, 90, 100});
canvas->drawImage(image, 0, 0);
canvas->drawImage(subset, 128, 0);
SkPaint paint;
SkString s;
s.printf("original id: %d", image->uniqueID());
canvas->drawString(s, 20, image->height() + 20, paint);
s.printf("subset id: %d", subset->uniqueID());
canvas->drawString(s, 148, subset->height() + 20, paint);
##
#SeeAlso isLazyGenerated
#Method ##
# ------------------------------------------------------------------------------
#Method SkAlphaType alphaType() const
#In Property
#Line # returns Alpha_Type ##
Returns Alpha_Type, one of: #list_of_alpha_types#.
Alpha_Type returned was a parameter to an Image constructor,
or was parsed from encoded data.
#Return Alpha_Type in Image ##
#Example
#Image 4
#Height 96
const char* alphaTypeStr[] = { "Unknown", "Opaque", "Premul", "Unpremul" };
SkAlphaType alphaType = image->alphaType();
canvas->drawImage(image, 16, 0);
canvas->drawString(alphaTypeStr[(int) alphaType], 20, image->height() + 20, SkPaint());
##
#SeeAlso SkImageInfo::alphaType
#Method ##
# ------------------------------------------------------------------------------
#Method SkColorType colorType() const
#In Property
#Line # returns Color_Type ##
#Populate
#Example
#Image 4
#Height 96
const char* colors[] = { "Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
"BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16" };
SkColorType colorType = image->colorType();
canvas->drawImage(image, 16, 0);
canvas->drawString(colors[(int) colorType], 20, image->height() + 20, SkPaint());
##
#SeeAlso SkImageInfo::colorType
#Method ##
# ------------------------------------------------------------------------------
#Method SkColorSpace* colorSpace() const
#In Property
#Line # returns Color_Space ##
#Populate
#Example
#Image 3
#Set sRGB
SkPixmap pixmap;
source.peekPixels(&pixmap);
canvas->scale(.25f, .25f);
int y = 0;
for (auto gamma : { SkNamedTransferFn::kLinear,
SkNamedTransferFn::kSRGB } ) {
int x = 0;
sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeRGB(gamma, SkNamedGamut::kSRGB);
for (int index = 0; index < 2; ++index) {
pixmap.setColorSpace(colorSpace);
sk_sp<SkImage> image = SkImage::MakeRasterCopy(pixmap);
canvas->drawImage(image, x, y);
colorSpace = image->colorSpace()->makeColorSpin();
x += 512;
}
y += 512;
}
##
#SeeAlso refColorSpace makeColorSpace
#Method ##
# ------------------------------------------------------------------------------
#Method sk_sp<SkColorSpace> refColorSpace() const
#In Property
#Line # returns Image_Info Color_Space ##
#Populate
#Example
#Image 3
#Set sRGB
SkPixmap pixmap;
source.peekPixels(&pixmap);
canvas->scale(.25f, .25f);
int y = 0;
for (auto gamma : { SkNamedTransferFn::kLinear,
SkNamedTransferFn::kSRGB } ) {
int x = 0;
sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeRGB(gamma, SkNamedGamut::kSRGB);
for (int index = 0; index < 2; ++index) {
pixmap.setColorSpace(colorSpace);
sk_sp<SkImage> image = SkImage::MakeRasterCopy(pixmap);
canvas->drawImage(image, x, y);
colorSpace = image->refColorSpace()->makeColorSpin();
x += 512;
}
y += 512;
}
##
#SeeAlso colorSpace makeColorSpace
#Method ##
# ------------------------------------------------------------------------------
#Method bool isAlphaOnly() const
#In Property
#Line # returns if pixels represent a transparency mask ##
#Populate
#Example
uint8_t pmColors = 0;
sk_sp<SkImage> image = SkImage::MakeRasterCopy({SkImageInfo::MakeA8(1, 1), &pmColors, 1});
SkDebugf("alphaOnly = %s\n", image->isAlphaOnly() ? "true" : "false");
#StdOut
alphaOnly = true
##
##
#SeeAlso alphaType isOpaque
#Method ##
# ------------------------------------------------------------------------------
#Method bool isOpaque() const
#In Property
#Line # returns if Alpha_Type is kOpaque_SkAlphaType ##
#Populate
#Example
auto check_isopaque = [](const SkImageInfo& imageInfo) -> void {
auto surface(SkSurface::MakeRaster(imageInfo));
auto image(surface->makeImageSnapshot());
SkDebugf("isOpaque = %s\n", image->isOpaque() ? "true" : "false");
};
check_isopaque(SkImageInfo::MakeN32Premul(5, 5));
check_isopaque(SkImageInfo::MakeN32(5, 5, kOpaque_SkAlphaType));
#StdOut
isOpaque = false
isOpaque = true
##
##
#SeeAlso alphaType isAlphaOnly
#Method ##
# ------------------------------------------------------------------------------
#Method sk_sp<SkShader> makeShader(SkShader::TileMode tileMode1, SkShader::TileMode tileMode2,
const SkMatrix* localMatrix = nullptr) const
#In Constructors
#Line # creates Shader, Paint element that can tile Image ##
#Populate
#Example
#Image 4
SkMatrix matrix;
matrix.setRotate(45);
SkPaint paint;
paint.setShader(image->makeShader(SkShader::kRepeat_TileMode, SkShader::kMirror_TileMode,
&matrix));
canvas->drawPaint(paint);
##
#SeeAlso scalePixels
#Method ##
# ------------------------------------------------------------------------------
#Method sk_sp<SkShader> makeShader(const SkMatrix* localMatrix = nullptr) const
#Populate
#Example
#Image 5
SkMatrix matrix;
matrix.setRotate(45);
matrix.postTranslate(125, 30);
SkPaint paint;
paint.setShader(image->makeShader(&matrix));
canvas->drawPaint(paint);
##
#SeeAlso scalePixels
#Method ##
# ------------------------------------------------------------------------------
#Subtopic Pixels
#Line # read and write pixel values ##
##
#Method bool peekPixels(SkPixmap* pixmap) const
#In Pixels
#Line # returns Pixmap if possible ##
#Populate
#Example
SkBitmap bitmap;
bitmap.allocPixels(SkImageInfo::MakeN32Premul(12, 11));
SkCanvas offscreen(bitmap);
offscreen.clear(SK_ColorWHITE);
SkPaint paint;
offscreen.drawString("%", 1, 10, paint);
sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
SkPixmap pixmap;
if (image->peekPixels(&pixmap)) {
const SkPMColor* pixels = pixmap.addr32();
SkPMColor pmWhite = pixels[0];
for (int y = 0; y < image->height(); ++y) {
for (int x = 0; x < image->width(); ++x) {
SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
}
SkDebugf("\n");
}
}
#StdOut
------------
--xx----x---
-x--x--x----
-x--x--x----
-x--x-x-----
--xx-xx-xx--
-----x-x--x-
----x--x--x-
----x--x--x-
---x----xx--
------------
##
##
#SeeAlso readPixels
#Method ##
# ------------------------------------------------------------------------------
#Method bool isTextureBacked() const
#In Property
#Line # returns if Image was created from GPU_Texture ##
#Populate
#Example
#Image 5
#Platform gpu
auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {
if (nullptr == image) {
return;
}
SkPaint paint;
paint.setAntiAlias(true);
canvas->drawImage(image, 0, 0);
canvas->drawString(label, 30, image->height() / 4, paint);
canvas->drawString(image->isTextureBacked() ? "is GPU texture" : "not GPU texture",
20, image->height() * 3 / 4, paint);
};
sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
kOpaque_SkAlphaType, nullptr));
drawImage(image, "image");
canvas->translate(image->width(), 0);
drawImage(bitmapImage, "source");
canvas->translate(-image->width(), image->height());
drawImage(textureImage, "backEndTexture");
##
#SeeAlso MakeFromTexture isValid
#Method ##
# ------------------------------------------------------------------------------
#Method bool isValid(GrContext* context) const
#In Property
#Line # returns if Image can draw to Raster_Surface or GPU_Context ##
#Populate
#Example
#Image 5
#Platform gpu
auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {
if (nullptr == image) {
return;
}
SkPaint paint;
paint.setAntiAlias(true);
canvas->drawImage(image, 0, 0);
canvas->drawString(label, image->width() / 2, image->height() / 4, paint);
if (canvas->getGrContext()) {
canvas->drawString(image->isValid(canvas->getGrContext()) ? "is valid on GPU" :
"not valid on GPU", 20, image->height() * 5 / 8, paint);
}
canvas->drawString(image->isValid(nullptr) ? "is valid on CPU" :
"not valid on CPU", 20, image->height() * 7 / 8, paint);
};
sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
kOpaque_SkAlphaType, nullptr));
drawImage(image, "image");
canvas->translate(image->width(), 0);
drawImage(bitmapImage, "source");
canvas->translate(-image->width(), image->height());
drawImage(textureImage, "backEndTexture");
##
#SeeAlso isTextureBacked isLazyGenerated
#Method ##
# ------------------------------------------------------------------------------
#Method GrBackendTexture getBackendTexture(bool flushPendingGrContextIO,
GrSurfaceOrigin* origin = nullptr) const
#In Property
#Line # returns GPU reference to Image as texture ##
#Populate
#Example
#Image 3
#Platform gpu
GrContext* grContext = canvas->getGrContext();
if (!grContext) {
canvas->drawString("GPU only!", 20, 40, SkPaint());
return;
}
sk_sp<SkImage> imageFromBackend = SkImage::MakeFromAdoptedTexture(grContext, backEndTexture,
kBottomLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
GrBackendTexture textureFromImage = imageFromBackend->getBackendTexture(false);
if (!textureFromImage.isValid()) {
return;
}
sk_sp<SkImage> imageFromTexture = SkImage::MakeFromAdoptedTexture(grContext, textureFromImage,
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
canvas->drawImage(imageFromTexture, 0, 0);
canvas->drawImage(imageFromBackend, 128, 128);
##
#SeeAlso MakeFromTexture isTextureBacked
#Method ##
# ------------------------------------------------------------------------------
#Enum CachingHint
#Line # options for readPixels and scalePixels ##
#Code
#Populate
##
CachingHint selects whether Skia may internally cache Bitmaps generated by
decoding Image, or by copying Image from GPU to CPU. The default behavior
allows caching Bitmaps.
Choose kDisallow_CachingHint if Image pixels are to be used only once, or
if Image pixels reside in a cache outside of Skia, or to reduce memory pressure.
Choosing kAllow_CachingHint does not ensure that pixels will be cached.
Image pixels may not be cached if memory requirements are too large or
pixels are not accessible.
#Const kAllow_CachingHint 0
#Line # allows internally caching decoded and copied pixels ##
##
#Const kDisallow_CachingHint 1
#Line # disallows internally caching decoded and copied pixels ##
##
#NoExample
##
#SeeAlso readPixels scalePixels
#Enum ##
# ------------------------------------------------------------------------------
#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
int srcX, int srcY, CachingHint cachingHint = kAllow_CachingHint) const
#In Pixels
#Line # copies and converts pixels ##
Copies Rect of pixels from Image to dstPixels. Copy starts at offset (srcX, srcY),
and does not exceed Image (width(), height()).
dstInfo specifies width, height, Color_Type, Alpha_Type, and Color_Space of
destination. dstRowBytes specifics the gap from one destination row to the next.
Returns true if pixels are copied. Returns false if:
#List
# dstInfo has no address ##
# dstRowBytes is less than dstInfo.minRowBytes() ##
# Pixel_Ref is nullptr ##
##
Pixels are copied only if pixel conversion is possible. If Image Color_Type is
kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType() must match.
If Image Color_Type is kGray_8_SkColorType, dstInfo.colorSpace() must match.
If Image Alpha_Type is kOpaque_SkAlphaType, dstInfo.alphaType() must
match. If Image Color_Space is nullptr, dstInfo.colorSpace() must match. Returns
false if pixel conversion is not possible.
srcX and srcY may be negative to copy only top or left of source. Returns
false if width() or height() is zero or negative.
Returns false if #Formula # abs(srcX) >= Image width() ##, or if #Formula # abs(srcY) >= Image height() ##.
If cachingHint is kAllow_CachingHint, pixels may be retained locally.
If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
#Param dstInfo destination width, height, Color_Type, Alpha_Type, Color_Space ##
#Param dstPixels destination pixel storage ##
#Param dstRowBytes destination row length ##
#Param srcX column index whose absolute value is less than width() ##
#Param srcY row index whose absolute value is less than height() ##
#Param cachingHint one of: kAllow_CachingHint, kDisallow_CachingHint ##
#Return true if pixels are copied to dstPixels ##
#Example
#Image 3
canvas->scale(.5f, .5f);
const int width = 32;
const int height = 32;
std::vector<int32_t> dstPixels;
dstPixels.resize(height * width * 4);
SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
for (int y = 0; y < 512; y += height ) {
for (int x = 0; x < 512; x += width ) {
if (image->readPixels(info, &dstPixels.front(), width * 4, x, y)) {
SkPixmap dstPixmap(info, &dstPixels.front(), width * 4);
SkBitmap bitmap;
bitmap.installPixels(dstPixmap);
canvas->drawBitmap(bitmap, 0, 0);
}
canvas->translate(48, 0);
}
canvas->translate(-16 * 48, 48);
}
##
#SeeAlso scalePixels SkBitmap::readPixels SkPixmap::readPixels SkCanvas::readPixels SkSurface::readPixels
#Method ##
# ------------------------------------------------------------------------------
#Method bool readPixels(const SkPixmap& dst, int srcX, int srcY,
CachingHint cachingHint = kAllow_CachingHint) const
Copies a Rect of pixels from Image to dst. Copy starts at (srcX, srcY), and
does not exceed Image (width(), height()).
dst specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
and row bytes of destination. dst.rowBytes() specifics the gap from one destination
row to the next. Returns true if pixels are copied. Returns false if:
#List
# dst pixel storage equals nullptr ##
# dst.rowBytes() is less than SkImageInfo::minRowBytes ##
# Pixel_Ref is nullptr ##
##
Pixels are copied only if pixel conversion is possible. If Image Color_Type is
kGray_8_SkColorType, or kAlpha_8_SkColorType; dst.colorType() must match.
If Image Color_Type is kGray_8_SkColorType, dst.colorSpace() must match.
If Image Alpha_Type is kOpaque_SkAlphaType, dst.alphaType() must
match. If Image Color_Space is nullptr, dst.colorSpace() must match. Returns
false if pixel conversion is not possible.
srcX and srcY may be negative to copy only top or left of source. Returns
false if width() or height() is zero or negative.
Returns false if #Formula # abs(srcX) >= Image width() ##, or if #Formula # abs(srcY) >= Image height() ##.
If cachingHint is kAllow_CachingHint, pixels may be retained locally.
If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
#Param dst destination Pixmap: Image_Info, pixels, row bytes ##
#Param srcX column index whose absolute value is less than width() ##
#Param srcY row index whose absolute value is less than height() ##
#Param cachingHint one of: kAllow_CachingHint, kDisallow_CachingHint ##
#Return true if pixels are copied to dst ##
#Example
#Image 3
std::vector<int32_t> srcPixels;
int rowBytes = image->width() * 4;
int quarterWidth = image->width() / 4;
int quarterHeight = image->height() / 4;
srcPixels.resize(image->height() * rowBytes);
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
SkPixmap pixmap(SkImageInfo::MakeN32Premul(quarterWidth, quarterHeight),
&srcPixels.front() + x * image->height() * quarterWidth +
y * quarterWidth, rowBytes);
image->readPixels(pixmap, x * quarterWidth, y * quarterHeight);
}
}
canvas->scale(.5f, .5f);
SkBitmap bitmap;
bitmap.installPixels(SkImageInfo::MakeN32Premul(image->width(), image->height()),
&srcPixels.front(), rowBytes);
canvas->drawBitmap(bitmap, 0, 0);
##
#SeeAlso scalePixels SkBitmap::readPixels SkPixmap::readPixels SkCanvas::readPixels SkSurface::readPixels
#Method ##
# ------------------------------------------------------------------------------
#Method bool scalePixels(const SkPixmap& dst, SkFilterQuality filterQuality,
CachingHint cachingHint = kAllow_CachingHint) const
#In Pixels
#Line # scales and converts one Image to another ##
#Populate
#Example
#Image 3
#Height 128
std::vector<int32_t> srcPixels;
int quarterWidth = image->width() / 16;
int rowBytes = quarterWidth * 4;
int quarterHeight = image->height() / 16;
srcPixels.resize(quarterHeight * rowBytes);
SkPixmap pixmap(SkImageInfo::MakeN32Premul(quarterWidth, quarterHeight),
&srcPixels.front(), rowBytes);
canvas->scale(4, 4);
SkFilterQuality qualities[] = { kNone_SkFilterQuality, kLow_SkFilterQuality,
kMedium_SkFilterQuality, kHigh_SkFilterQuality };
for (unsigned index = 0; index < SK_ARRAY_COUNT(qualities); ++index) {
image->scalePixels(pixmap, qualities[index]);
sk_sp<SkImage> filtered = SkImage::MakeFromRaster(pixmap, nullptr, nullptr);
canvas->drawImage(filtered, 16 * index, 0);
}
##
#SeeAlso SkCanvas::drawImage readPixels SkPixmap::scalePixels
#Method ##
# ------------------------------------------------------------------------------
#Method sk_sp<SkData> encodeToData(SkEncodedImageFormat encodedImageFormat, int quality) const
#In Utility
#Line # returns encoded Image as SkData ##
#Populate
#Example
#Image 3
canvas->scale(4, 4);
SkIRect subset = {0, 0, 16, 64};
int x = 0;
for (int quality : { 0, 10, 50, 100 } ) {
sk_sp<SkData> data(image->encodeToData(SkEncodedImageFormat::kJPEG, quality));
sk_sp<SkImage> filtered = SkImage::MakeFromEncoded(data, &subset);
canvas->drawImage(filtered, x, 0);
x += 16;
}
##
#SeeAlso refEncodedData MakeFromEncoded
#Method ##
# ------------------------------------------------------------------------------
#Method sk_sp<SkData> encodeToData() const
#Populate
#Example
#Image 3
canvas->scale(4, 4);
SkIRect subset = {136, 32, 200, 96};
sk_sp<SkData> data(image->encodeToData());
sk_sp<SkImage> eye = SkImage::MakeFromEncoded(data, &subset);
canvas->drawImage(eye, 0, 0);
##
#SeeAlso refEncodedData MakeFromEncoded
#Method ##
# ------------------------------------------------------------------------------
#Method sk_sp<SkData> refEncodedData() const
#In Utility
#Line # returns Image encoded in SkData if present ##
#Populate
#Example
#Image 3
#Platform gpu
struct {
const char* name;
sk_sp<SkImage> image;
} tests[] = { { "image", image }, { "bitmap", SkImage::MakeFromBitmap(source) },
{ "texture", SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
kOpaque_SkAlphaType, nullptr) } };
SkString string;
SkPaint paint;
for (const auto& test : tests ) {
if (!test.image) {
string.printf("no %s", test.name);
} else {
string.printf("%s" "encoded %s", test.image->refEncodedData() ? "" : "no ", test.name);
}
canvas->drawString(string, 10, 20, paint);
canvas->translate(0, 20);
}
##
#SeeAlso encodeToData MakeFromEncoded
#Method ##
# ------------------------------------------------------------------------------
#Subtopic Utility
#Line # rarely called management functions ##
##
#Method sk_sp<SkImage> makeSubset(const SkIRect& subset) const
#In Constructors
#Line # creates Image containing part of original ##
#Populate
#Example
#Image 3
canvas->scale(.5f, .5f);
const int width = 64;
const int height = 64;
for (int y = 0; y < 512; y += height ) {
for (int x = 0; x < 512; x += width ) {
sk_sp<SkImage> subset(image->makeSubset({x, y, x + width, y + height}));
canvas->drawImage(subset, x * 3 / 2, y * 3 / 2);
}
}
##
#SeeAlso MakeFromEncoded
#Method ##
# ------------------------------------------------------------------------------
#Method sk_sp<SkImage> makeTextureImage(GrContext* context, SkColorSpace* dstColorSpace,
GrMipMapped mipMapped = GrMipMapped::kNo) const
#In Constructors
#Line # creates Image matching Color_Space if possible ##
#Populate
#Example
#Platform gpu
#Image 5
auto drawImage = [=](sk_sp<SkImage> image, GrContext* context, const char* label) -> void {
if (nullptr == image || nullptr == context) {
return;
}
SkPaint paint;
paint.setAntiAlias(true);
sk_sp<SkImage> texture(image->makeTextureImage(context, nullptr));
canvas->drawImage(texture, 0, 0);
canvas->drawString(label, 20, texture->height() / 4, paint);
};
sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
GrContext* context = canvas->getGrContext();
sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(context, backEndTexture,
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
kOpaque_SkAlphaType, nullptr));
drawImage(image, context, "image");
canvas->translate(image->width(), 0);
drawImage(bitmapImage, context, "source");
canvas->translate(-image->width(), image->height());
drawImage(textureImage, context, "backEndTexture");
##
#SeeAlso MakeFromTexture
#Method ##
# ------------------------------------------------------------------------------
#Method sk_sp<SkImage> makeNonTextureImage() const
#In Constructors
#Line # creates Image without dependency on GPU_Texture ##
#Populate
#Example
#Image 5
#Platform gpu
auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {
if (nullptr == image) {
return;
}
SkPaint paint;
paint.setAntiAlias(true);
sk_sp<SkImage> nonTexture(image->makeNonTextureImage());
canvas->drawImage(nonTexture, 0, 0);
canvas->drawString(label, 20, nonTexture->height() / 4, paint);
};
sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
kOpaque_SkAlphaType, nullptr));
drawImage(image, "image");
canvas->translate(image->width(), 0);
drawImage(bitmapImage, "source");
canvas->translate(-image->width(), image->height());
drawImage(textureImage, "backEndTexture");
##
#SeeAlso makeTextureImage makeRasterImage MakeBackendTextureFromSkImage
#Method ##
# ------------------------------------------------------------------------------
#Method sk_sp<SkImage> makeRasterImage() const
#In Constructors
#Line # creates Image compatible with Raster_Surface if possible ##
#Populate
#Example
#Image 5
#Platform gpu
auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {
if (nullptr == image) {
return;
}
SkPaint paint;
paint.setAntiAlias(true);
sk_sp<SkImage> raster(image->makeRasterImage());
canvas->drawImage(raster, 0, 0);
canvas->drawString(label, 20, raster->height() / 4, paint);
};
sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
kOpaque_SkAlphaType, nullptr));
drawImage(image, "image");
canvas->translate(image->width(), 0);
drawImage(bitmapImage, "source");
canvas->translate(-image->width(), image->height());
drawImage(textureImage, "backEndTexture");
##
#SeeAlso isTextureBacked isLazyGenerated MakeFromRaster
#Method ##
# ------------------------------------------------------------------------------
#Method sk_sp<SkImage> makeWithFilter(GrContext* context,
const SkImageFilter* filter, const SkIRect& subset,
const SkIRect& clipBounds, SkIRect* outSubset,
SkIPoint* offset) const
#In Constructors
#Line # creates filtered, clipped Image ##
#Populate
#Example
#Description
In each frame of the animation, filtered Image is drawn in a different location.
By translating canvas by returned offset, Image appears stationary.
##
#Image 5
#Platform gpu
#Duration 1
sk_sp<SkImageFilter> shadowFilter = SkDropShadowImageFilter::Make(
-10.0f * frame, 5.0f * frame, 3.0f, 3.0f, SK_ColorBLUE,
SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
nullptr);
sk_sp<SkImageFilter> offsetFilter = SkOffsetImageFilter::Make(40, 40, shadowFilter, nullptr);
SkIRect subset = image->bounds();
SkIRect clipBounds = image->bounds();
clipBounds.outset(60, 60);
SkIRect outSubset;
SkIPoint offset;
sk_sp<SkImage> filtered(image->makeWithFilter(canvas->getGrContext(),
offsetFilter.get(), subset, clipBounds,
&outSubset, &offset));
SkPaint paint;
paint.setAntiAlias(true);
paint.setStyle(SkPaint::kStroke_Style);
canvas->drawLine(0, 0, offset.fX, offset.fY, paint);
canvas->translate(offset.fX, offset.fY);
canvas->drawImage(filtered, 0, 0);
canvas->drawRect(SkRect::Make(outSubset), paint);
##
#SeeAlso makeShader SkPaint::setImageFilter
#Method ##
# ------------------------------------------------------------------------------
#Method sk_sp<SkImage> makeWithFilter(const SkImageFilter* filter, const SkIRect& subset,
const SkIRect& clipBounds, SkIRect* outSubset,
SkIPoint* offset) const
#In Constructors
#Line # creates filtered, clipped Image ##
#Populate
#NoExample
##
#SeeAlso makeShader SkPaint::setImageFilter
#Method ##
# ------------------------------------------------------------------------------
#Typedef std::function<void(GrBackendTexture)> BackendTextureReleaseProc
#Line # parameter type for MakeBackendTextureFromSkImage ##
#Code
#Populate
##
Defines a callback function, taking one parameter of type GrBackendTexture with
no return value. Function is called when back-end texture is to be released.
##
# ------------------------------------------------------------------------------
#Method static bool MakeBackendTextureFromSkImage(GrContext* context,
sk_sp<SkImage> image,
GrBackendTexture* backendTexture,
BackendTextureReleaseProc* backendTextureReleaseProc)
#In Constructors
#Line # creates GPU_Texture from Image ##
#Populate
#Example
#Platform gpu
#Height 64
#Function
static sk_sp<SkImage> create_gpu_image(GrContext* grContext) {
const SkImageInfo info = SkImageInfo::MakeN32(20, 20, kOpaque_SkAlphaType);
auto surface(SkSurface::MakeRenderTarget(grContext, SkBudgeted::kNo, info));
SkCanvas* canvas = surface->getCanvas();
canvas->clear(SK_ColorWHITE);
SkPaint paint;
paint.setColor(SK_ColorBLACK);
canvas->drawRect(SkRect::MakeXYWH(5, 5, 10, 10), paint);
return surface->makeImageSnapshot();
}
##
void draw(SkCanvas* canvas) {
GrContext* grContext = canvas->getGrContext();
if (!grContext) {
return;
}
sk_sp<SkImage> backEndImage = create_gpu_image(grContext);
canvas->drawImage(backEndImage, 0, 0);
GrBackendTexture texture;
SkImage::BackendTextureReleaseProc proc;
if (!SkImage::MakeBackendTextureFromSkImage(grContext, std::move(backEndImage),
&texture, &proc)) {
return;
}
sk_sp<SkImage> i2 = SkImage::MakeFromTexture(grContext, texture, kTopLeft_GrSurfaceOrigin,
kN32_SkColorType, kOpaque_SkAlphaType, nullptr);
canvas->drawImage(i2, 30, 30);
}
##
#SeeAlso MakeFromTexture makeTextureImage
#Method ##
# ------------------------------------------------------------------------------
#Method bool isLazyGenerated() const
#In Property
#Line # returns if Image is created as needed ##
#Populate
#Example
#Height 80
#Function
class TestImageGenerator : public SkImageGenerator {
public:
TestImageGenerator() : SkImageGenerator(SkImageInfo::MakeN32Premul(10, 10)) {}
~TestImageGenerator() override {}
protected:
bool onGetPixels(const SkImageInfo& info, void* pixelPtr, size_t rowBytes,
const Options& options) override {
SkPMColor* pixels = static_cast<SkPMColor*>(pixelPtr);
for (int y = 0; y < info.height(); ++y) {
for (int x = 0; x < info.width(); ++x) {
pixels[y * info.width() + x] = 0xff223344 + y * 0x000C0811;
}
}
return true;
}
};
##
void draw(SkCanvas* canvas) {
auto gen = std::unique_ptr<TestImageGenerator>(new TestImageGenerator());
sk_sp<SkImage> image(SkImage::MakeFromGenerator(std::move(gen)));
SkString lazy(image->isLazyGenerated() ? "is lazy" : "not lazy");
canvas->scale(8, 8);
canvas->drawImage(image, 0, 0, nullptr);
SkPaint paint;
paint.setTextSize(4);
canvas->drawString(lazy, 2, 5, paint);
}
##
#Example
#Image 5
#Platform gpu
void draw(SkCanvas* canvas) {
auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {
if (nullptr == image) {
return;
}
SkPaint paint;
paint.setAntiAlias(true);
canvas->drawImage(image, 0, 0);
canvas->drawString(label, 30, image->height() / 4, paint);
canvas->drawString(
image->isLazyGenerated() ? "is lazily generated" : "not lazily generated",
20, image->height() * 3 / 4, paint);
};
sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
kOpaque_SkAlphaType, nullptr));
drawImage(image, "image");
canvas->translate(image->width(), 0);
drawImage(bitmapImage, "source");
canvas->translate(-image->width(), image->height());
drawImage(textureImage, "backEndTexture");
}
##
#SeeAlso isTextureBacked makeNonTextureImage
#Method ##
# ------------------------------------------------------------------------------
#Method sk_sp<SkImage> makeColorSpace(sk_sp<SkColorSpace> target) const
#In Constructors
#Line # creates Image matching Color_Space if possible ##
#Populate
#Example
#Image 5
#Set sRGB
sk_sp<SkColorSpace> normalColorSpace = SkColorSpace::MakeRGB(
SkNamedTransferFn::kSRGB, SkNamedGamut::kSRGB);
sk_sp<SkColorSpace> wackyColorSpace = normalColorSpace->makeColorSpin();
for (auto colorSpace : { normalColorSpace, wackyColorSpace } ) {
sk_sp<SkImage> colorSpaced = image->makeColorSpace(colorSpace);
canvas->drawImage(colorSpaced, 0, 0);
canvas->translate(128, 0);
}
##
#SeeAlso MakeFromPicture MakeFromTexture
#Method ##
#Class SkImage ##
#Topic Image ##