c334df71b8
TBR=bsalomon@google.com Change-Id: Ib10e5337df623df253ca39df0e57097a39fe87d5 Reviewed-on: https://skia-review.googlesource.com/c/183321 Reviewed-by: Robert Phillips <robertphillips@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
1756 lines
56 KiB
Plaintext
1756 lines
56 KiB
Plaintext
#Topic Image
|
|
#Alias Image_Reference ##
|
|
|
|
#Class SkImage
|
|
|
|
#Code
|
|
#Populate
|
|
##
|
|
|
|
Image describes a two dimensional array of pixels to draw. The pixels may be
|
|
decoded in a Raster_Bitmap, encoded in a Picture or compressed data stream,
|
|
or located in GPU memory as a GPU_Texture.
|
|
|
|
Image cannot be modified after it is created. Image may allocate additional
|
|
storage as needed; for instance, an encoded Image may decode when drawn.
|
|
|
|
Image width and height are greater than zero. Creating an Image with zero width
|
|
or height returns Image equal to nullptr.
|
|
|
|
Image may be created from Bitmap, Pixmap, Surface, Picture, encoded streams,
|
|
GPU_Texture, YUV_ColorSpace data, or hardware buffer. Encoded streams supported
|
|
include BMP, GIF, HEIF, ICO, JPEG, PNG, WBMP, WebP. Supported encoding details
|
|
vary with platform.
|
|
|
|
#Subtopic Raster_Image
|
|
#Alias Raster_Image ##
|
|
#Line # pixels decoded in Raster_Bitmap ##
|
|
Raster_Image pixels are decoded in a Raster_Bitmap. These pixels may be read
|
|
directly and in most cases written to, although edited pixels may not be drawn
|
|
if Image has been copied internally.
|
|
##
|
|
|
|
#Subtopic Texture_Image
|
|
#Line # pixels located on GPU ##
|
|
Texture_Image are located on GPU and pixels are not accessible. Texture_Image
|
|
are allocated optimally for best performance. Raster_Image may
|
|
be drawn to GPU_Surface, but pixels are uploaded from CPU to GPU downgrading
|
|
performance.
|
|
##
|
|
|
|
#Subtopic Lazy_Image
|
|
#Line # deferred pixel buffer ##
|
|
Lazy_Image defer allocating buffer for Image pixels and decoding stream until
|
|
Image is drawn. Lazy_Image caches result if possible to speed up repeated
|
|
drawing.
|
|
##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method static sk_sp<SkImage> MakeRasterCopy(const SkPixmap& pixmap)
|
|
#In Constructors
|
|
#Line # creates Image from Pixmap and copied pixels ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Height 50
|
|
#Description
|
|
Draw a five by five bitmap, and draw a copy in an Image. Editing the pixmap
|
|
alters the bitmap draw, but does not alter the Image draw since the Image
|
|
contains a copy of the pixels.
|
|
##
|
|
uint8_t storage[][5] = {{ 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 },
|
|
{ 0xAC, 0xA8, 0x89, 0xA7, 0x87 },
|
|
{ 0x9B, 0xB5, 0xE5, 0x95, 0x46 },
|
|
{ 0x90, 0x81, 0xC5, 0x71, 0x33 },
|
|
{ 0x75, 0x55, 0x44, 0x40, 0x30 }};
|
|
SkImageInfo imageInfo = SkImageInfo::Make(5, 5, kGray_8_SkColorType, kOpaque_SkAlphaType);
|
|
SkPixmap pixmap(imageInfo, storage[0], sizeof(storage) / 5);
|
|
SkBitmap bitmap;
|
|
bitmap.installPixels(pixmap);
|
|
sk_sp<SkImage> image = SkImage::MakeRasterCopy(pixmap);
|
|
*pixmap.writable_addr8(2, 2) = 0x00;
|
|
canvas->scale(10, 10);
|
|
canvas->drawBitmap(bitmap, 0, 0);
|
|
canvas->drawImage(image, 10, 0);
|
|
##
|
|
|
|
#SeeAlso MakeRasterData MakeFromGenerator
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method static sk_sp<SkImage> MakeRasterData(const SkImageInfo& info, sk_sp<SkData> pixels, size_t rowBytes)
|
|
#In Constructors
|
|
#Line # creates Image from Image_Info and shared pixels ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Image 3
|
|
size_t rowBytes = image->width() * SkColorTypeBytesPerPixel(kRGBA_8888_SkColorType);
|
|
sk_sp<SkData> data = SkData::MakeUninitialized(rowBytes * image->height());
|
|
SkImageInfo dstInfo = SkImageInfo::MakeN32(image->width(), image->height(),
|
|
kPremul_SkAlphaType);
|
|
image->readPixels(dstInfo, data->writable_data(), rowBytes, 0, 0, SkImage::kAllow_CachingHint);
|
|
sk_sp<SkImage> raw = SkImage::MakeRasterData(dstInfo.makeColorType(kRGBA_8888_SkColorType),
|
|
data, rowBytes);
|
|
canvas->drawImage(image, 0, 0);
|
|
canvas->drawImage(raw.get(), 128, 0);
|
|
##
|
|
|
|
#SeeAlso MakeRasterCopy MakeFromGenerator
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Typedef void* ReleaseContext
|
|
#Line # parameter type for MakeFromRaster ##
|
|
|
|
#Code
|
|
#Populate
|
|
##
|
|
|
|
Caller data passed to RasterReleaseProc; may be nullptr.
|
|
|
|
#SeeAlso MakeFromRaster RasterReleaseProc
|
|
|
|
##
|
|
|
|
#Typedef void (*RasterReleaseProc)(const void* pixels, ReleaseContext)
|
|
#Line # parameter type for MakeFromRaster ##
|
|
|
|
#Code
|
|
#Populate
|
|
##
|
|
|
|
Function called when Image no longer shares pixels. ReleaseContext is
|
|
provided by caller when Image is created, and may be nullptr.
|
|
|
|
#SeeAlso ReleaseContext MakeFromRaster
|
|
|
|
##
|
|
|
|
#Method static sk_sp<SkImage> MakeFromRaster(const SkPixmap& pixmap,
|
|
RasterReleaseProc rasterReleaseProc,
|
|
ReleaseContext releaseContext)
|
|
#In Constructors
|
|
#Line # creates Image from Pixmap, with release ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Function
|
|
static void releaseProc(const void* pixels, SkImage::ReleaseContext context) {
|
|
int* countPtr = static_cast<int*>(context);
|
|
*countPtr += 1;
|
|
}
|
|
##
|
|
|
|
void draw(SkCanvas* canvas) {
|
|
SkColor color = 0;
|
|
SkPixmap pixmap(SkImageInfo::MakeN32(1, 1, kPremul_SkAlphaType), &color, 4);
|
|
int releaseCount = 0;
|
|
sk_sp<SkImage> image(SkImage::MakeFromRaster(pixmap, releaseProc, &releaseCount));
|
|
SkDebugf("before reset: %d\n", releaseCount);
|
|
image.reset();
|
|
SkDebugf("after reset: %d\n", releaseCount);
|
|
}
|
|
#StdOut
|
|
before reset: 0
|
|
after reset: 1
|
|
##
|
|
##
|
|
|
|
#SeeAlso MakeRasterCopy MakeRasterData MakeFromGenerator RasterReleaseProc ReleaseContext
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method static sk_sp<SkImage> MakeFromBitmap(const SkBitmap& bitmap)
|
|
#In Constructors
|
|
#Line # creates Image from Bitmap, sharing or copying pixels ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Description
|
|
The first Bitmap is shared; writing to the pixel memory changes the first
|
|
Image.
|
|
The second Bitmap is marked immutable, and is copied; writing to the pixel
|
|
memory does not alter the second Image.
|
|
##
|
|
#Height 50
|
|
uint8_t storage[][5] = {{ 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 },
|
|
{ 0xAC, 0xA8, 0x89, 0xA7, 0x87 },
|
|
{ 0x9B, 0xB5, 0xE5, 0x95, 0x46 },
|
|
{ 0x90, 0x81, 0xC5, 0x71, 0x33 },
|
|
{ 0x75, 0x55, 0x44, 0x40, 0x30 }};
|
|
SkImageInfo imageInfo = SkImageInfo::Make(5, 5, kGray_8_SkColorType, kOpaque_SkAlphaType);
|
|
SkPixmap pixmap(imageInfo, storage[0], sizeof(storage) / 5);
|
|
SkBitmap bitmap;
|
|
bitmap.installPixels(pixmap);
|
|
sk_sp<SkImage> image1 = SkImage::MakeFromBitmap(bitmap);
|
|
bitmap.setImmutable();
|
|
sk_sp<SkImage> image2 = SkImage::MakeFromBitmap(bitmap);
|
|
*pixmap.writable_addr8(2, 2) = 0x00;
|
|
canvas->scale(10, 10);
|
|
canvas->drawImage(image1, 0, 0);
|
|
canvas->drawImage(image2, 10, 0);
|
|
##
|
|
|
|
#SeeAlso MakeFromRaster MakeRasterCopy MakeFromGenerator MakeRasterData
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method static sk_sp<SkImage> MakeFromGenerator(std::unique_ptr<SkImageGenerator> imageGenerator,
|
|
const SkIRect* subset = nullptr)
|
|
#In Constructors
|
|
#Line # creates Image from a stream of data ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Height 128
|
|
#Description
|
|
The generator returning Picture cannot be shared; std::move transfers ownership to generated Image.
|
|
##
|
|
SkPictureRecorder recorder;
|
|
recorder.beginRecording(100, 100)->drawColor(SK_ColorRED);
|
|
auto picture = recorder.finishRecordingAsPicture();
|
|
auto gen = SkImageGenerator::MakeFromPicture({100, 100}, picture, nullptr, nullptr,
|
|
SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB());
|
|
sk_sp<SkImage> image = SkImage::MakeFromGenerator(std::move(gen));
|
|
canvas->drawImage(image, 0, 0);
|
|
##
|
|
|
|
#SeeAlso MakeFromEncoded
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method static sk_sp<SkImage> MakeFromEncoded(sk_sp<SkData> encoded, const SkIRect* subset = nullptr)
|
|
#In Constructors
|
|
#Line # creates Image from encoded data ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Image 3
|
|
int x = 0;
|
|
for (int quality : { 100, 50, 10, 1} ) {
|
|
sk_sp<SkData> encodedData = image->encodeToData(SkEncodedImageFormat::kJPEG, quality);
|
|
sk_sp<SkImage> image = SkImage::MakeFromEncoded(encodedData);
|
|
canvas->drawImage(image, x, 0);
|
|
x += 64;
|
|
}
|
|
##
|
|
|
|
#SeeAlso MakeFromGenerator
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#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 : { SkColorSpace::kLinear_RenderTargetGamma,
|
|
SkColorSpace::kSRGB_RenderTargetGamma } ) {
|
|
int x = 0;
|
|
sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeRGB(gamma, SkColorSpace::kSRGB_Gamut);
|
|
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 : { SkColorSpace::kLinear_RenderTargetGamma,
|
|
SkColorSpace::kSRGB_RenderTargetGamma } ) {
|
|
int x = 0;
|
|
sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeRGB(gamma, SkColorSpace::kSRGB_Gamut);
|
|
for (int index = 0; index < 2; ++index) {
|
|
pixmap.setColorSpace(colorSpace);
|
|
sk_sp<SkImage> image = SkImage::MakeRasterCopy(pixmap);
|
|
canvas->drawImage(image, x, y);
|
|
colorSpace = image->refColorSpace()->makeColorSpin();
|
|
x += 512;
|
|
}
|
|
y += 512;
|
|
}
|
|
##
|
|
|
|
#SeeAlso colorSpace makeColorSpace
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method bool isAlphaOnly() const
|
|
#In Property
|
|
#Line # returns if pixels represent a transparency mask ##
|
|
#Populate
|
|
|
|
#Example
|
|
uint8_t pmColors = 0;
|
|
sk_sp<SkImage> image = SkImage::MakeRasterCopy({SkImageInfo::MakeA8(1, 1), &pmColors, 1});
|
|
SkDebugf("alphaOnly = %s\n", image->isAlphaOnly() ? "true" : "false");
|
|
#StdOut
|
|
alphaOnly = true
|
|
##
|
|
##
|
|
|
|
#SeeAlso alphaType isOpaque
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method bool isOpaque() const
|
|
#In Property
|
|
#Line # returns if Alpha_Type is kOpaque_SkAlphaType ##
|
|
#Populate
|
|
|
|
#Example
|
|
auto check_isopaque = [](const SkImageInfo& imageInfo) -> void {
|
|
auto surface(SkSurface::MakeRaster(imageInfo));
|
|
auto image(surface->makeImageSnapshot());
|
|
SkDebugf("isOpaque = %s\n", image->isOpaque() ? "true" : "false");
|
|
};
|
|
|
|
check_isopaque(SkImageInfo::MakeN32Premul(5, 5));
|
|
check_isopaque(SkImageInfo::MakeN32(5, 5, kOpaque_SkAlphaType));
|
|
#StdOut
|
|
isOpaque = false
|
|
isOpaque = true
|
|
##
|
|
##
|
|
|
|
#SeeAlso alphaType isAlphaOnly
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method sk_sp<SkShader> makeShader(SkShader::TileMode tileMode1, SkShader::TileMode tileMode2,
|
|
const SkMatrix* localMatrix = nullptr) const
|
|
#In Constructors
|
|
#Line # creates Shader, Paint element that can tile Image ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Image 4
|
|
SkMatrix matrix;
|
|
matrix.setRotate(45);
|
|
SkPaint paint;
|
|
paint.setShader(image->makeShader(SkShader::kRepeat_TileMode, SkShader::kMirror_TileMode,
|
|
&matrix));
|
|
canvas->drawPaint(paint);
|
|
##
|
|
|
|
#SeeAlso scalePixels
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method sk_sp<SkShader> makeShader(const SkMatrix* localMatrix = nullptr) const
|
|
#Populate
|
|
|
|
#Example
|
|
#Image 5
|
|
SkMatrix matrix;
|
|
matrix.setRotate(45);
|
|
matrix.postTranslate(125, 30);
|
|
SkPaint paint;
|
|
paint.setShader(image->makeShader(&matrix));
|
|
canvas->drawPaint(paint);
|
|
##
|
|
|
|
#SeeAlso scalePixels
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
#Subtopic Pixels
|
|
#Line # read and write pixel values ##
|
|
##
|
|
|
|
#Method bool peekPixels(SkPixmap* pixmap) const
|
|
#In Pixels
|
|
#Line # returns Pixmap if possible ##
|
|
#Populate
|
|
|
|
#Example
|
|
SkBitmap bitmap;
|
|
bitmap.allocPixels(SkImageInfo::MakeN32Premul(12, 11));
|
|
SkCanvas offscreen(bitmap);
|
|
offscreen.clear(SK_ColorWHITE);
|
|
SkPaint paint;
|
|
offscreen.drawString("%", 1, 10, paint);
|
|
sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
|
|
SkPixmap pixmap;
|
|
if (image->peekPixels(&pixmap)) {
|
|
const SkPMColor* pixels = pixmap.addr32();
|
|
SkPMColor pmWhite = pixels[0];
|
|
for (int y = 0; y < image->height(); ++y) {
|
|
for (int x = 0; x < image->width(); ++x) {
|
|
SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
|
|
}
|
|
SkDebugf("\n");
|
|
}
|
|
}
|
|
#StdOut
|
|
------------
|
|
--xx----x---
|
|
-x--x--x----
|
|
-x--x--x----
|
|
-x--x-x-----
|
|
--xx-xx-xx--
|
|
-----x-x--x-
|
|
----x--x--x-
|
|
----x--x--x-
|
|
---x----xx--
|
|
------------
|
|
##
|
|
##
|
|
|
|
#SeeAlso readPixels
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method bool isTextureBacked() const
|
|
#In Property
|
|
#Line # returns if Image was created from GPU_Texture ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Image 5
|
|
#Platform gpu
|
|
auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {
|
|
if (nullptr == image) {
|
|
return;
|
|
}
|
|
SkPaint paint;
|
|
paint.setAntiAlias(true);
|
|
canvas->drawImage(image, 0, 0);
|
|
canvas->drawString(label, 30, image->height() / 4, paint);
|
|
canvas->drawString(image->isTextureBacked() ? "is GPU texture" : "not GPU texture",
|
|
20, image->height() * 3 / 4, paint);
|
|
};
|
|
sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
|
|
sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
|
|
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
|
|
kOpaque_SkAlphaType, nullptr));
|
|
drawImage(image, "image");
|
|
canvas->translate(image->width(), 0);
|
|
drawImage(bitmapImage, "source");
|
|
canvas->translate(-image->width(), image->height());
|
|
drawImage(textureImage, "backEndTexture");
|
|
##
|
|
|
|
#SeeAlso MakeFromTexture isValid
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method bool isValid(GrContext* context) const
|
|
#In Property
|
|
#Line # returns if Image can draw to Raster_Surface or GPU_Context ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Image 5
|
|
#Platform gpu
|
|
auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {
|
|
if (nullptr == image) {
|
|
return;
|
|
}
|
|
SkPaint paint;
|
|
paint.setAntiAlias(true);
|
|
canvas->drawImage(image, 0, 0);
|
|
canvas->drawString(label, image->width() / 2, image->height() / 4, paint);
|
|
if (canvas->getGrContext()) {
|
|
canvas->drawString(image->isValid(canvas->getGrContext()) ? "is valid on GPU" :
|
|
"not valid on GPU", 20, image->height() * 5 / 8, paint);
|
|
}
|
|
canvas->drawString(image->isValid(nullptr) ? "is valid on CPU" :
|
|
"not valid on CPU", 20, image->height() * 7 / 8, paint);
|
|
};
|
|
sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
|
|
sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
|
|
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
|
|
kOpaque_SkAlphaType, nullptr));
|
|
drawImage(image, "image");
|
|
canvas->translate(image->width(), 0);
|
|
drawImage(bitmapImage, "source");
|
|
canvas->translate(-image->width(), image->height());
|
|
drawImage(textureImage, "backEndTexture");
|
|
##
|
|
|
|
#SeeAlso isTextureBacked isLazyGenerated
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method GrBackendTexture getBackendTexture(bool flushPendingGrContextIO,
|
|
GrSurfaceOrigin* origin = nullptr) const
|
|
#In Property
|
|
#Line # returns GPU reference to Image as texture ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Image 3
|
|
#Platform gpu
|
|
GrContext* grContext = canvas->getGrContext();
|
|
if (!grContext) {
|
|
canvas->drawString("GPU only!", 20, 40, SkPaint());
|
|
return;
|
|
}
|
|
sk_sp<SkImage> imageFromBackend = SkImage::MakeFromAdoptedTexture(grContext, backEndTexture,
|
|
kBottomLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
|
|
GrBackendTexture textureFromImage = imageFromBackend->getBackendTexture(false);
|
|
if (!textureFromImage.isValid()) {
|
|
return;
|
|
}
|
|
sk_sp<SkImage> imageFromTexture = SkImage::MakeFromAdoptedTexture(grContext, textureFromImage,
|
|
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
|
|
canvas->drawImage(imageFromTexture, 0, 0);
|
|
canvas->drawImage(imageFromBackend, 128, 128);
|
|
##
|
|
|
|
#SeeAlso MakeFromTexture isTextureBacked
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Enum CachingHint
|
|
#Line # options for readPixels and scalePixels ##
|
|
#Code
|
|
#Populate
|
|
##
|
|
|
|
CachingHint selects whether Skia may internally cache Bitmaps generated by
|
|
decoding Image, or by copying Image from GPU to CPU. The default behavior
|
|
allows caching Bitmaps.
|
|
|
|
Choose kDisallow_CachingHint if Image pixels are to be used only once, or
|
|
if Image pixels reside in a cache outside of Skia, or to reduce memory pressure.
|
|
|
|
Choosing kAllow_CachingHint does not ensure that pixels will be cached.
|
|
Image pixels may not be cached if memory requirements are too large or
|
|
pixels are not accessible.
|
|
|
|
#Const kAllow_CachingHint 0
|
|
#Line # allows internally caching decoded and copied pixels ##
|
|
##
|
|
#Const kDisallow_CachingHint 1
|
|
#Line # disallows internally caching decoded and copied pixels ##
|
|
##
|
|
|
|
#NoExample
|
|
##
|
|
|
|
#SeeAlso readPixels scalePixels
|
|
|
|
#Enum ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
|
|
int srcX, int srcY, CachingHint cachingHint = kAllow_CachingHint) const
|
|
#In Pixels
|
|
#Line # copies and converts pixels ##
|
|
|
|
Copies Rect of pixels from Image to dstPixels. Copy starts at offset (srcX, srcY),
|
|
and does not exceed Image (width(), height()).
|
|
|
|
dstInfo specifies width, height, Color_Type, Alpha_Type, and Color_Space of
|
|
destination. dstRowBytes specifics the gap from one destination row to the next.
|
|
Returns true if pixels are copied. Returns false if:
|
|
#List
|
|
# dstInfo has no address ##
|
|
# dstRowBytes is less than dstInfo.minRowBytes() ##
|
|
# Pixel_Ref is nullptr ##
|
|
##
|
|
|
|
Pixels are copied only if pixel conversion is possible. If Image Color_Type is
|
|
kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType() must match.
|
|
If Image Color_Type is kGray_8_SkColorType, dstInfo.colorSpace() must match.
|
|
If Image Alpha_Type is kOpaque_SkAlphaType, dstInfo.alphaType() must
|
|
match. If Image Color_Space is nullptr, dstInfo.colorSpace() must match. Returns
|
|
false if pixel conversion is not possible.
|
|
|
|
srcX and srcY may be negative to copy only top or left of source. Returns
|
|
false if width() or height() is zero or negative.
|
|
Returns false if #Formula # abs(srcX) >= Image width() ##, or if #Formula # abs(srcY) >= Image height() ##.
|
|
|
|
If cachingHint is kAllow_CachingHint, pixels may be retained locally.
|
|
If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
|
|
|
|
#Param dstInfo destination width, height, Color_Type, Alpha_Type, Color_Space ##
|
|
#Param dstPixels destination pixel storage ##
|
|
#Param dstRowBytes destination row length ##
|
|
#Param srcX column index whose absolute value is less than width() ##
|
|
#Param srcY row index whose absolute value is less than height() ##
|
|
#Param cachingHint one of: kAllow_CachingHint, kDisallow_CachingHint ##
|
|
|
|
#Return true if pixels are copied to dstPixels ##
|
|
|
|
#Example
|
|
#Image 3
|
|
canvas->scale(.5f, .5f);
|
|
const int width = 32;
|
|
const int height = 32;
|
|
std::vector<int32_t> dstPixels;
|
|
dstPixels.resize(height * width * 4);
|
|
SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
|
|
for (int y = 0; y < 512; y += height ) {
|
|
for (int x = 0; x < 512; x += width ) {
|
|
if (image->readPixels(info, &dstPixels.front(), width * 4, x, y)) {
|
|
SkPixmap dstPixmap(info, &dstPixels.front(), width * 4);
|
|
SkBitmap bitmap;
|
|
bitmap.installPixels(dstPixmap);
|
|
canvas->drawBitmap(bitmap, 0, 0);
|
|
}
|
|
canvas->translate(48, 0);
|
|
}
|
|
canvas->translate(-16 * 48, 48);
|
|
}
|
|
##
|
|
|
|
#SeeAlso scalePixels SkBitmap::readPixels SkPixmap::readPixels SkCanvas::readPixels SkSurface::readPixels
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method bool readPixels(const SkPixmap& dst, int srcX, int srcY,
|
|
CachingHint cachingHint = kAllow_CachingHint) const
|
|
|
|
Copies a Rect of pixels from Image to dst. Copy starts at (srcX, srcY), and
|
|
does not exceed Image (width(), height()).
|
|
|
|
dst specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
|
|
and row bytes of destination. dst.rowBytes() specifics the gap from one destination
|
|
row to the next. Returns true if pixels are copied. Returns false if:
|
|
#List
|
|
# dst pixel storage equals nullptr ##
|
|
# dst.rowBytes() is less than SkImageInfo::minRowBytes ##
|
|
# Pixel_Ref is nullptr ##
|
|
##
|
|
|
|
Pixels are copied only if pixel conversion is possible. If Image Color_Type is
|
|
kGray_8_SkColorType, or kAlpha_8_SkColorType; dst.colorType() must match.
|
|
If Image Color_Type is kGray_8_SkColorType, dst.colorSpace() must match.
|
|
If Image Alpha_Type is kOpaque_SkAlphaType, dst.alphaType() must
|
|
match. If Image Color_Space is nullptr, dst.colorSpace() must match. Returns
|
|
false if pixel conversion is not possible.
|
|
|
|
srcX and srcY may be negative to copy only top or left of source. Returns
|
|
false if width() or height() is zero or negative.
|
|
Returns false if #Formula # abs(srcX) >= Image width() ##, or if #Formula # abs(srcY) >= Image height() ##.
|
|
|
|
If cachingHint is kAllow_CachingHint, pixels may be retained locally.
|
|
If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
|
|
|
|
#Param dst destination Pixmap: Image_Info, pixels, row bytes ##
|
|
#Param srcX column index whose absolute value is less than width() ##
|
|
#Param srcY row index whose absolute value is less than height() ##
|
|
#Param cachingHint one of: kAllow_CachingHint, kDisallow_CachingHint ##
|
|
|
|
#Return true if pixels are copied to dst ##
|
|
|
|
#Example
|
|
#Image 3
|
|
std::vector<int32_t> srcPixels;
|
|
int rowBytes = image->width() * 4;
|
|
int quarterWidth = image->width() / 4;
|
|
int quarterHeight = image->height() / 4;
|
|
srcPixels.resize(image->height() * rowBytes);
|
|
for (int y = 0; y < 4; ++y) {
|
|
for (int x = 0; x < 4; ++x) {
|
|
SkPixmap pixmap(SkImageInfo::MakeN32Premul(quarterWidth, quarterHeight),
|
|
&srcPixels.front() + x * image->height() * quarterWidth +
|
|
y * quarterWidth, rowBytes);
|
|
image->readPixels(pixmap, x * quarterWidth, y * quarterHeight);
|
|
}
|
|
}
|
|
canvas->scale(.5f, .5f);
|
|
SkBitmap bitmap;
|
|
bitmap.installPixels(SkImageInfo::MakeN32Premul(image->width(), image->height()),
|
|
&srcPixels.front(), rowBytes);
|
|
canvas->drawBitmap(bitmap, 0, 0);
|
|
##
|
|
|
|
#SeeAlso scalePixels SkBitmap::readPixels SkPixmap::readPixels SkCanvas::readPixels SkSurface::readPixels
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method bool scalePixels(const SkPixmap& dst, SkFilterQuality filterQuality,
|
|
CachingHint cachingHint = kAllow_CachingHint) const
|
|
#In Pixels
|
|
#Line # scales and converts one Image to another ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Image 3
|
|
#Height 128
|
|
std::vector<int32_t> srcPixels;
|
|
int quarterWidth = image->width() / 16;
|
|
int rowBytes = quarterWidth * 4;
|
|
int quarterHeight = image->height() / 16;
|
|
srcPixels.resize(quarterHeight * rowBytes);
|
|
SkPixmap pixmap(SkImageInfo::MakeN32Premul(quarterWidth, quarterHeight),
|
|
&srcPixels.front(), rowBytes);
|
|
canvas->scale(4, 4);
|
|
SkFilterQuality qualities[] = { kNone_SkFilterQuality, kLow_SkFilterQuality,
|
|
kMedium_SkFilterQuality, kHigh_SkFilterQuality };
|
|
for (unsigned index = 0; index < SK_ARRAY_COUNT(qualities); ++index) {
|
|
image->scalePixels(pixmap, qualities[index]);
|
|
sk_sp<SkImage> filtered = SkImage::MakeFromRaster(pixmap, nullptr, nullptr);
|
|
canvas->drawImage(filtered, 16 * index, 0);
|
|
}
|
|
##
|
|
|
|
#SeeAlso SkCanvas::drawImage readPixels SkPixmap::scalePixels
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method sk_sp<SkData> encodeToData(SkEncodedImageFormat encodedImageFormat, int quality) const
|
|
#In Utility
|
|
#Line # returns encoded Image as SkData ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Image 3
|
|
canvas->scale(4, 4);
|
|
SkIRect subset = {0, 0, 16, 64};
|
|
int x = 0;
|
|
for (int quality : { 0, 10, 50, 100 } ) {
|
|
sk_sp<SkData> data(image->encodeToData(SkEncodedImageFormat::kJPEG, quality));
|
|
sk_sp<SkImage> filtered = SkImage::MakeFromEncoded(data, &subset);
|
|
canvas->drawImage(filtered, x, 0);
|
|
x += 16;
|
|
}
|
|
##
|
|
|
|
#SeeAlso refEncodedData MakeFromEncoded
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method sk_sp<SkData> encodeToData() const
|
|
#Populate
|
|
|
|
#Example
|
|
#Image 3
|
|
canvas->scale(4, 4);
|
|
SkIRect subset = {136, 32, 200, 96};
|
|
sk_sp<SkData> data(image->encodeToData());
|
|
sk_sp<SkImage> eye = SkImage::MakeFromEncoded(data, &subset);
|
|
canvas->drawImage(eye, 0, 0);
|
|
##
|
|
|
|
#SeeAlso refEncodedData MakeFromEncoded
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method sk_sp<SkData> refEncodedData() const
|
|
#In Utility
|
|
#Line # returns Image encoded in SkData if present ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Image 3
|
|
#Platform gpu
|
|
struct {
|
|
const char* name;
|
|
sk_sp<SkImage> image;
|
|
} tests[] = { { "image", image }, { "bitmap", SkImage::MakeFromBitmap(source) },
|
|
{ "texture", SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
|
|
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
|
|
kOpaque_SkAlphaType, nullptr) } };
|
|
SkString string;
|
|
SkPaint paint;
|
|
for (const auto& test : tests ) {
|
|
if (!test.image) {
|
|
string.printf("no %s", test.name);
|
|
} else {
|
|
string.printf("%s" "encoded %s", test.image->refEncodedData() ? "" : "no ", test.name);
|
|
}
|
|
canvas->drawString(string, 10, 20, paint);
|
|
canvas->translate(0, 20);
|
|
}
|
|
##
|
|
|
|
#SeeAlso encodeToData MakeFromEncoded
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
#Subtopic Utility
|
|
#Line # rarely called management functions ##
|
|
##
|
|
|
|
#Method sk_sp<SkImage> makeSubset(const SkIRect& subset) const
|
|
#In Constructors
|
|
#Line # creates Image containing part of original ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Image 3
|
|
canvas->scale(.5f, .5f);
|
|
const int width = 64;
|
|
const int height = 64;
|
|
for (int y = 0; y < 512; y += height ) {
|
|
for (int x = 0; x < 512; x += width ) {
|
|
sk_sp<SkImage> subset(image->makeSubset({x, y, x + width, y + height}));
|
|
canvas->drawImage(subset, x * 3 / 2, y * 3 / 2);
|
|
}
|
|
}
|
|
##
|
|
|
|
#SeeAlso MakeFromEncoded
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method sk_sp<SkImage> makeTextureImage(GrContext* context, SkColorSpace* dstColorSpace,
|
|
GrMipMapped mipMapped = GrMipMapped::kNo) const
|
|
#In Constructors
|
|
#Line # creates Image matching Color_Space if possible ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Platform gpu
|
|
#Image 5
|
|
auto drawImage = [=](sk_sp<SkImage> image, GrContext* context, const char* label) -> void {
|
|
if (nullptr == image || nullptr == context) {
|
|
return;
|
|
}
|
|
SkPaint paint;
|
|
paint.setAntiAlias(true);
|
|
sk_sp<SkImage> texture(image->makeTextureImage(context, nullptr));
|
|
canvas->drawImage(texture, 0, 0);
|
|
canvas->drawString(label, 20, texture->height() / 4, paint);
|
|
};
|
|
sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
|
|
GrContext* context = canvas->getGrContext();
|
|
sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(context, backEndTexture,
|
|
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
|
|
kOpaque_SkAlphaType, nullptr));
|
|
drawImage(image, context, "image");
|
|
canvas->translate(image->width(), 0);
|
|
drawImage(bitmapImage, context, "source");
|
|
canvas->translate(-image->width(), image->height());
|
|
drawImage(textureImage, context, "backEndTexture");
|
|
##
|
|
|
|
#SeeAlso MakeFromTexture
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method sk_sp<SkImage> makeNonTextureImage() const
|
|
#In Constructors
|
|
#Line # creates Image without dependency on GPU_Texture ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Image 5
|
|
#Platform gpu
|
|
auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {
|
|
if (nullptr == image) {
|
|
return;
|
|
}
|
|
SkPaint paint;
|
|
paint.setAntiAlias(true);
|
|
sk_sp<SkImage> nonTexture(image->makeNonTextureImage());
|
|
canvas->drawImage(nonTexture, 0, 0);
|
|
canvas->drawString(label, 20, nonTexture->height() / 4, paint);
|
|
};
|
|
sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
|
|
sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
|
|
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
|
|
kOpaque_SkAlphaType, nullptr));
|
|
drawImage(image, "image");
|
|
canvas->translate(image->width(), 0);
|
|
drawImage(bitmapImage, "source");
|
|
canvas->translate(-image->width(), image->height());
|
|
drawImage(textureImage, "backEndTexture");
|
|
##
|
|
|
|
#SeeAlso makeTextureImage makeRasterImage MakeBackendTextureFromSkImage
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method sk_sp<SkImage> makeRasterImage() const
|
|
#In Constructors
|
|
#Line # creates Image compatible with Raster_Surface if possible ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Image 5
|
|
#Platform gpu
|
|
auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {
|
|
if (nullptr == image) {
|
|
return;
|
|
}
|
|
SkPaint paint;
|
|
paint.setAntiAlias(true);
|
|
sk_sp<SkImage> raster(image->makeRasterImage());
|
|
canvas->drawImage(raster, 0, 0);
|
|
canvas->drawString(label, 20, raster->height() / 4, paint);
|
|
};
|
|
sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
|
|
sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
|
|
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
|
|
kOpaque_SkAlphaType, nullptr));
|
|
drawImage(image, "image");
|
|
canvas->translate(image->width(), 0);
|
|
drawImage(bitmapImage, "source");
|
|
canvas->translate(-image->width(), image->height());
|
|
drawImage(textureImage, "backEndTexture");
|
|
##
|
|
|
|
#SeeAlso isTextureBacked isLazyGenerated MakeFromRaster
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method sk_sp<SkImage> makeWithFilter(GrContext* context,
|
|
const SkImageFilter* filter, const SkIRect& subset,
|
|
const SkIRect& clipBounds, SkIRect* outSubset,
|
|
SkIPoint* offset) const
|
|
#In Constructors
|
|
#Line # creates filtered, clipped Image ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Description
|
|
In each frame of the animation, filtered Image is drawn in a different location.
|
|
By translating canvas by returned offset, Image appears stationary.
|
|
##
|
|
#Image 5
|
|
#Platform gpu
|
|
#Duration 1
|
|
sk_sp<SkImageFilter> shadowFilter = SkDropShadowImageFilter::Make(
|
|
-10.0f * frame, 5.0f * frame, 3.0f, 3.0f, SK_ColorBLUE,
|
|
SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
|
|
nullptr);
|
|
sk_sp<SkImageFilter> offsetFilter = SkOffsetImageFilter::Make(40, 40, shadowFilter, nullptr);
|
|
SkIRect subset = image->bounds();
|
|
SkIRect clipBounds = image->bounds();
|
|
clipBounds.outset(60, 60);
|
|
SkIRect outSubset;
|
|
SkIPoint offset;
|
|
sk_sp<SkImage> filtered(image->makeWithFilter(canvas->getGrContext(),
|
|
offsetFilter.get(), subset, clipBounds,
|
|
&outSubset, &offset));
|
|
SkPaint paint;
|
|
paint.setAntiAlias(true);
|
|
paint.setStyle(SkPaint::kStroke_Style);
|
|
canvas->drawLine(0, 0, offset.fX, offset.fY, paint);
|
|
canvas->translate(offset.fX, offset.fY);
|
|
canvas->drawImage(filtered, 0, 0);
|
|
canvas->drawRect(SkRect::Make(outSubset), paint);
|
|
##
|
|
|
|
#SeeAlso makeShader SkPaint::setImageFilter
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method sk_sp<SkImage> makeWithFilter(const SkImageFilter* filter, const SkIRect& subset,
|
|
const SkIRect& clipBounds, SkIRect* outSubset,
|
|
SkIPoint* offset) const
|
|
#In Constructors
|
|
#Line # creates filtered, clipped Image ##
|
|
#Populate
|
|
#NoExample
|
|
##
|
|
#SeeAlso makeShader SkPaint::setImageFilter
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Typedef std::function<void(GrBackendTexture)> BackendTextureReleaseProc
|
|
#Line # parameter type for MakeBackendTextureFromSkImage ##
|
|
|
|
#Code
|
|
#Populate
|
|
##
|
|
|
|
Defines a callback function, taking one parameter of type GrBackendTexture with
|
|
no return value. Function is called when back-end texture is to be released.
|
|
##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method static bool MakeBackendTextureFromSkImage(GrContext* context,
|
|
sk_sp<SkImage> image,
|
|
GrBackendTexture* backendTexture,
|
|
BackendTextureReleaseProc* backendTextureReleaseProc)
|
|
#In Constructors
|
|
#Line # creates GPU_Texture from Image ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Platform gpu
|
|
#Height 64
|
|
#Function
|
|
static sk_sp<SkImage> create_gpu_image(GrContext* grContext) {
|
|
const SkImageInfo info = SkImageInfo::MakeN32(20, 20, kOpaque_SkAlphaType);
|
|
auto surface(SkSurface::MakeRenderTarget(grContext, SkBudgeted::kNo, info));
|
|
SkCanvas* canvas = surface->getCanvas();
|
|
canvas->clear(SK_ColorWHITE);
|
|
SkPaint paint;
|
|
paint.setColor(SK_ColorBLACK);
|
|
canvas->drawRect(SkRect::MakeXYWH(5, 5, 10, 10), paint);
|
|
return surface->makeImageSnapshot();
|
|
}
|
|
##
|
|
|
|
void draw(SkCanvas* canvas) {
|
|
GrContext* grContext = canvas->getGrContext();
|
|
if (!grContext) {
|
|
return;
|
|
}
|
|
sk_sp<SkImage> backEndImage = create_gpu_image(grContext);
|
|
canvas->drawImage(backEndImage, 0, 0);
|
|
GrBackendTexture texture;
|
|
SkImage::BackendTextureReleaseProc proc;
|
|
if (!SkImage::MakeBackendTextureFromSkImage(grContext, std::move(backEndImage),
|
|
&texture, &proc)) {
|
|
return;
|
|
}
|
|
sk_sp<SkImage> i2 = SkImage::MakeFromTexture(grContext, texture, kTopLeft_GrSurfaceOrigin,
|
|
kN32_SkColorType, kOpaque_SkAlphaType, nullptr);
|
|
canvas->drawImage(i2, 30, 30);
|
|
}
|
|
##
|
|
|
|
#SeeAlso MakeFromTexture makeTextureImage
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method bool isLazyGenerated() const
|
|
#In Property
|
|
#Line # returns if Image is created as needed ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Height 80
|
|
#Function
|
|
class TestImageGenerator : public SkImageGenerator {
|
|
public:
|
|
TestImageGenerator() : SkImageGenerator(SkImageInfo::MakeN32Premul(10, 10)) {}
|
|
~TestImageGenerator() override {}
|
|
protected:
|
|
bool onGetPixels(const SkImageInfo& info, void* pixelPtr, size_t rowBytes,
|
|
const Options& options) override {
|
|
SkPMColor* pixels = static_cast<SkPMColor*>(pixelPtr);
|
|
for (int y = 0; y < info.height(); ++y) {
|
|
for (int x = 0; x < info.width(); ++x) {
|
|
pixels[y * info.width() + x] = 0xff223344 + y * 0x000C0811;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
##
|
|
void draw(SkCanvas* canvas) {
|
|
auto gen = std::unique_ptr<TestImageGenerator>(new TestImageGenerator());
|
|
sk_sp<SkImage> image(SkImage::MakeFromGenerator(std::move(gen)));
|
|
SkString lazy(image->isLazyGenerated() ? "is lazy" : "not lazy");
|
|
canvas->scale(8, 8);
|
|
canvas->drawImage(image, 0, 0, nullptr);
|
|
SkPaint paint;
|
|
paint.setTextSize(4);
|
|
canvas->drawString(lazy, 2, 5, paint);
|
|
}
|
|
##
|
|
|
|
#Example
|
|
#Image 5
|
|
#Platform gpu
|
|
void draw(SkCanvas* canvas) {
|
|
auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {
|
|
if (nullptr == image) {
|
|
return;
|
|
}
|
|
SkPaint paint;
|
|
paint.setAntiAlias(true);
|
|
canvas->drawImage(image, 0, 0);
|
|
canvas->drawString(label, 30, image->height() / 4, paint);
|
|
canvas->drawString(
|
|
image->isLazyGenerated() ? "is lazily generated" : "not lazily generated",
|
|
20, image->height() * 3 / 4, paint);
|
|
};
|
|
sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
|
|
sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
|
|
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
|
|
kOpaque_SkAlphaType, nullptr));
|
|
drawImage(image, "image");
|
|
canvas->translate(image->width(), 0);
|
|
drawImage(bitmapImage, "source");
|
|
canvas->translate(-image->width(), image->height());
|
|
drawImage(textureImage, "backEndTexture");
|
|
}
|
|
##
|
|
|
|
#SeeAlso isTextureBacked makeNonTextureImage
|
|
|
|
#Method ##
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
#Method sk_sp<SkImage> makeColorSpace(sk_sp<SkColorSpace> target) const
|
|
#In Constructors
|
|
#Line # creates Image matching Color_Space if possible ##
|
|
#Populate
|
|
|
|
#Example
|
|
#Image 5
|
|
#Set sRGB
|
|
sk_sp<SkColorSpace> normalColorSpace = SkColorSpace::MakeRGB(
|
|
SkColorSpace::kSRGB_RenderTargetGamma, SkColorSpace::kSRGB_Gamut);
|
|
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 ##
|