| #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 ## | |
| # ------------------------------------------------------------------------------ | |
| #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; | |
| SkFont font(nullptr, 4); | |
| canvas->drawString(lazy, 2, 5, font, 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 ## |