#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 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 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 MakeRasterData(const SkImageInfo& info, sk_sp 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 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 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 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(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 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 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 image1 = SkImage::MakeFromBitmap(bitmap); bitmap.setImmutable(); sk_sp 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 MakeFromGenerator(std::unique_ptr 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 image = SkImage::MakeFromGenerator(std::move(gen)); canvas->drawImage(image, 0, 0); ## #SeeAlso MakeFromEncoded #Method ## # ------------------------------------------------------------------------------ #Method static sk_sp MakeFromEncoded(sk_sp 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 encodedData = image->encodeToData(SkEncodedImageFormat::kJPEG, quality); sk_sp image = SkImage::MakeFromEncoded(encodedData); canvas->drawImage(image, x, 0); x += 64; } ## #SeeAlso MakeFromGenerator #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 MakeFromTexture(GrContext* context, const GrBackendTexture& backendTexture, GrSurfaceOrigin origin, SkColorType colorType, SkAlphaType alphaType, sk_sp 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 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 MakeFromTexture(GrContext* context, const GrBackendTexture& backendTexture, GrSurfaceOrigin origin, SkColorType colorType, SkAlphaType alphaType, sk_sp 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 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 MakeCrossContextFromEncoded(GrContext* context, sk_sp 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 encodedData = image->encodeToData(SkEncodedImageFormat::kJPEG, 100); sk_sp image = SkImage::MakeCrossContextFromEncoded(context, encodedData, false, nullptr); canvas->drawImage(image, 0, 0); ## #SeeAlso MakeCrossContextFromPixmap #Method ## # ------------------------------------------------------------------------------ #Method static sk_sp 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 image = SkImage::MakeCrossContextFromPixmap(context, pixmap, false, nullptr); canvas->drawImage(image, 0, 0); } ## #SeeAlso MakeCrossContextFromEncoded #Method ## # ------------------------------------------------------------------------------ #Method static sk_sp MakeFromAdoptedTexture(GrContext* context, const GrBackendTexture& backendTexture, GrSurfaceOrigin surfaceOrigin, SkColorType colorType, SkAlphaType alphaType = kPremul_SkAlphaType, sk_sp 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 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 MakeFromYUVATexturesCopy(GrContext* context, SkYUVColorSpace yuvColorSpace, const GrBackendTexture yuvaTextures[], const SkYUVAIndex yuvaIndices[4], SkISize imageSize, GrSurfaceOrigin imageOrigin, sk_sp imageColorSpace = nullptr) #In Constructor #Line # creates Image from YUV_ColorSpace data ## #Populate #NoExample ## #SeeAlso MakeFromYUVATexturesCopyWithExternalBackend MakeFromYUVATextures #Method ## #Method static sk_sp MakeFromYUVATextures(GrContext* context, SkYUVColorSpace yuvColorSpace, const GrBackendTexture yuvaTextures[], const SkYUVAIndex yuvaIndices[4], SkISize imageSize, GrSurfaceOrigin imageOrigin, sk_sp imageColorSpace = nullptr); #In Constructor #Line # creates Image from YUV_ColorSpace data ## #Populate #NoExample ## #SeeAlso MakeFromYUVATexturesCopy MakeFromYUVATexturesCopyWithExternalBackend #Method ## #Method static sk_sp MakeFromYUVAPixmaps( GrContext* context, SkYUVColorSpace yuvColorSpace, const SkPixmap yuvaPixmaps[], const SkYUVAIndex yuvaIndices[4], SkISize imageSize, GrSurfaceOrigin imageOrigin, bool buildMips, bool limitToMaxTextureSize = false, sk_sp imageColorSpace = nullptr); #In Constructor #Line # creates Image from YUV_ColorSpace data ## #Populate #NoExample ## #SeeAlso MakeFromYUVATextures #Method ## # ------------------------------------------------------------------------------ #Method static sk_sp MakeFromYUVATexturesCopyWithExternalBackend( GrContext* context, SkYUVColorSpace yuvColorSpace, const GrBackendTexture yuvaTextures[], const SkYUVAIndex yuvaIndices[4], SkISize imageSize, GrSurfaceOrigin imageOrigin, const GrBackendTexture& backendTexture, sk_sp imageColorSpace = nullptr) #In Constructor #Line # creates Image from planar YUV_ColorSpace, stored in texture ## #Populate #NoExample ## #SeeAlso MakeFromYUVATexturesCopy MakeFromYUVATextures #Method ## #Method static sk_sp MakeFromYUVTexturesCopy(GrContext* context, SkYUVColorSpace yuvColorSpace, const GrBackendTexture yuvTextures[3], GrSurfaceOrigin imageOrigin, sk_sp 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 MakeFromYUVTexturesCopyWithExternalBackend( GrContext* context, SkYUVColorSpace yuvColorSpace, const GrBackendTexture yuvTextures[3], GrSurfaceOrigin imageOrigin, const GrBackendTexture& backendTexture, sk_sp 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 MakeFromNV12TexturesCopy(GrContext* context, SkYUVColorSpace yuvColorSpace, const GrBackendTexture nv12Textures[2], GrSurfaceOrigin imageOrigin, sk_sp 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 MakeFromNV12TexturesCopyWithExternalBackend( GrContext* context, SkYUVColorSpace yuvColorSpace, const GrBackendTexture nv12Textures[2], GrSurfaceOrigin imageOrigin, const GrBackendTexture& backendTexture, sk_sp 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 MakeFromPicture(sk_sp picture, const SkISize& dimensions, const SkMatrix* matrix, const SkPaint* paint, BitDepth bitDepth, sk_sp 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 playback = recorder.finishRecordingAsPicture(); int x = 0, y = 0; for (auto alpha : { 70, 140, 210 } ) { paint.setAlpha(alpha); auto srgbColorSpace = SkColorSpace::MakeSRGB(); sk_sp 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 MakeFromAHardwareBuffer( AHardwareBuffer* hardwareBuffer, SkAlphaType alphaType = kPremul_SkAlphaType, sk_sp 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 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 : { SkColorSpace::kLinear_RenderTargetGamma, SkColorSpace::kSRGB_RenderTargetGamma } ) { int x = 0; sk_sp colorSpace = SkColorSpace::MakeRGB(gamma, SkColorSpace::kSRGB_Gamut); for (int index = 0; index < 2; ++index) { pixmap.setColorSpace(colorSpace); sk_sp image = SkImage::MakeRasterCopy(pixmap); canvas->drawImage(image, x, y); colorSpace = image->colorSpace()->makeColorSpin(); x += 512; } y += 512; } ## #SeeAlso refColorSpace makeColorSpace #Method ## # ------------------------------------------------------------------------------ #Method sk_sp 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 : { SkColorSpace::kLinear_RenderTargetGamma, SkColorSpace::kSRGB_RenderTargetGamma } ) { int x = 0; sk_sp colorSpace = SkColorSpace::MakeRGB(gamma, SkColorSpace::kSRGB_Gamut); for (int index = 0; index < 2; ++index) { pixmap.setColorSpace(colorSpace); sk_sp 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 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 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 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 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 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 bitmapImage(SkImage::MakeFromBitmap(source)); sk_sp 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 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 bitmapImage(SkImage::MakeFromBitmap(source)); sk_sp 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 imageFromBackend = SkImage::MakeFromAdoptedTexture(grContext, backEndTexture, kBottomLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kOpaque_SkAlphaType); GrBackendTexture textureFromImage = imageFromBackend->getBackendTexture(false); if (!textureFromImage.isValid()) { return; } sk_sp 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 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 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 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 filtered = SkImage::MakeFromRaster(pixmap, nullptr, nullptr); canvas->drawImage(filtered, 16 * index, 0); } ## #SeeAlso SkCanvas::drawImage readPixels SkPixmap::scalePixels #Method ## # ------------------------------------------------------------------------------ #Method sk_sp 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 data(image->encodeToData(SkEncodedImageFormat::kJPEG, quality)); sk_sp filtered = SkImage::MakeFromEncoded(data, &subset); canvas->drawImage(filtered, x, 0); x += 16; } ## #SeeAlso refEncodedData MakeFromEncoded #Method ## # ------------------------------------------------------------------------------ #Method sk_sp encodeToData() const #Populate #Example #Image 3 canvas->scale(4, 4); SkIRect subset = {136, 32, 200, 96}; sk_sp data(image->encodeToData()); sk_sp eye = SkImage::MakeFromEncoded(data, &subset); canvas->drawImage(eye, 0, 0); ## #SeeAlso refEncodedData MakeFromEncoded #Method ## # ------------------------------------------------------------------------------ #Method sk_sp refEncodedData() const #In Utility #Line # returns Image encoded in SkData if present ## #Populate #Example #Image 3 #Platform gpu struct { const char* name; sk_sp 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 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 subset(image->makeSubset({x, y, x + width, y + height})); canvas->drawImage(subset, x * 3 / 2, y * 3 / 2); } } ## #SeeAlso MakeFromEncoded #Method ## # ------------------------------------------------------------------------------ #Method sk_sp 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 image, GrContext* context, const char* label) -> void { if (nullptr == image || nullptr == context) { return; } SkPaint paint; paint.setAntiAlias(true); sk_sp texture(image->makeTextureImage(context, nullptr)); canvas->drawImage(texture, 0, 0); canvas->drawString(label, 20, texture->height() / 4, paint); }; sk_sp bitmapImage(SkImage::MakeFromBitmap(source)); GrContext* context = canvas->getGrContext(); sk_sp 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 makeNonTextureImage() const #In Constructors #Line # creates Image without dependency on GPU_Texture ## #Populate #Example #Image 5 #Platform gpu auto drawImage = [=](sk_sp image, const char* label) -> void { if (nullptr == image) { return; } SkPaint paint; paint.setAntiAlias(true); sk_sp nonTexture(image->makeNonTextureImage()); canvas->drawImage(nonTexture, 0, 0); canvas->drawString(label, 20, nonTexture->height() / 4, paint); }; sk_sp bitmapImage(SkImage::MakeFromBitmap(source)); sk_sp 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 makeRasterImage() const #In Constructors #Line # creates Image compatible with Raster_Surface if possible ## #Populate #Example #Image 5 #Platform gpu auto drawImage = [=](sk_sp image, const char* label) -> void { if (nullptr == image) { return; } SkPaint paint; paint.setAntiAlias(true); sk_sp raster(image->makeRasterImage()); canvas->drawImage(raster, 0, 0); canvas->drawString(label, 20, raster->height() / 4, paint); }; sk_sp bitmapImage(SkImage::MakeFromBitmap(source)); sk_sp 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 makeWithFilter(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 shadowFilter = SkDropShadowImageFilter::Make( -10.0f * frame, 5.0f * frame, 3.0f, 3.0f, SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr); sk_sp 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 filtered(image->makeWithFilter(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 ## # ------------------------------------------------------------------------------ #Typedef std::function 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 image, GrBackendTexture* backendTexture, BackendTextureReleaseProc* backendTextureReleaseProc) #In Constructors #Line # creates GPU_Texture from Image ## #Populate #Example #Platform gpu #Height 64 #Function static sk_sp 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 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 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(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(new TestImageGenerator()); sk_sp 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 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 bitmapImage(SkImage::MakeFromBitmap(source)); sk_sp 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 makeColorSpace(sk_sp target) const #In Constructors #Line # creates Image matching Color_Space if possible ## #Populate #Example #Image 5 #Set sRGB sk_sp normalColorSpace = SkColorSpace::MakeRGB( SkColorSpace::kSRGB_RenderTargetGamma, SkColorSpace::kSRGB_Gamut); sk_sp wackyColorSpace = normalColorSpace->makeColorSpin(); for (auto colorSpace : { normalColorSpace, wackyColorSpace } ) { sk_sp colorSpaced = image->makeColorSpace(colorSpace); canvas->drawImage(colorSpaced, 0, 0); canvas->translate(128, 0); } ## #SeeAlso MakeFromPicture MakeFromTexture #Method ## #Class SkImage ## #Topic Image ##