Home | History | Annotate | Download | only in docs
      1 #Topic Image
      2 #Alias Image_Reference ##
      3 
      4 #Class SkImage
      5 
      6 #Code
      7 #Populate
      8 ##
      9 
     10 Image describes a two dimensional array of pixels to draw. The pixels may be
     11 decoded in a Raster_Bitmap, encoded in a Picture or compressed data stream,
     12 or located in GPU memory as a GPU_Texture.
     13 
     14 Image cannot be modified after it is created. Image may allocate additional
     15 storage as needed; for instance, an encoded Image may decode when drawn.
     16 
     17 Image width and height are greater than zero. Creating an Image with zero width
     18 or height returns Image equal to nullptr.
     19 
     20 Image may be created from Bitmap, Pixmap, Surface, Picture, encoded streams,
     21 GPU_Texture, YUV_ColorSpace data, or hardware buffer. Encoded streams supported
     22 include BMP, GIF, HEIF, ICO, JPEG, PNG, WBMP, WebP. Supported encoding details
     23 vary with platform.
     24 
     25 #Subtopic Raster_Image
     26 #Alias Raster_Image ##
     27 #Line # pixels decoded in Raster_Bitmap ##
     28 Raster_Image pixels are decoded in a Raster_Bitmap. These pixels may be read
     29 directly and in most cases written to, although edited pixels may not be drawn
     30 if Image has been copied internally.
     31 ##
     32 
     33 #Subtopic Texture_Image
     34 #Line # pixels located on GPU ##
     35 Texture_Image are located on GPU and pixels are not accessible. Texture_Image
     36 are allocated optimally for best performance. Raster_Image may
     37 be drawn to GPU_Surface, but pixels are uploaded from CPU to GPU downgrading
     38 performance.
     39 ##
     40 
     41 #Subtopic Lazy_Image
     42 #Line # deferred pixel buffer ##
     43 Lazy_Image defer allocating buffer for Image pixels and decoding stream until
     44 Image is drawn. Lazy_Image caches result if possible to speed up repeated
     45 drawing.
     46 ##
     47 
     48 # ------------------------------------------------------------------------------
     49 
     50 #Method static sk_sp<SkImage> MakeRasterCopy(const SkPixmap& pixmap)
     51 #In Constructors
     52 #Line # creates Image from Pixmap and copied pixels ##
     53 #Populate
     54 
     55 #Example
     56 #Height 50
     57 #Description
     58 Draw a five by five bitmap, and draw a copy in an Image. Editing the pixmap
     59 alters the bitmap draw, but does not alter the Image draw since the Image
     60 contains a copy of the pixels.
     61 ##
     62     uint8_t storage[][5] = {{ 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 },
     63                             { 0xAC, 0xA8, 0x89, 0xA7, 0x87 },
     64                             { 0x9B, 0xB5, 0xE5, 0x95, 0x46 },
     65                             { 0x90, 0x81, 0xC5, 0x71, 0x33 },
     66                             { 0x75, 0x55, 0x44, 0x40, 0x30 }};
     67     SkImageInfo imageInfo = SkImageInfo::Make(5, 5, kGray_8_SkColorType, kOpaque_SkAlphaType);
     68     SkPixmap pixmap(imageInfo, storage[0], sizeof(storage) / 5);
     69     SkBitmap bitmap;
     70     bitmap.installPixels(pixmap);
     71     sk_sp<SkImage> image = SkImage::MakeRasterCopy(pixmap);
     72     *pixmap.writable_addr8(2, 2) = 0x00;
     73     canvas->scale(10, 10);
     74     canvas->drawBitmap(bitmap, 0, 0);
     75     canvas->drawImage(image, 10, 0);
     76 ##
     77 
     78 #SeeAlso MakeRasterData MakeFromGenerator
     79 
     80 #Method ##
     81 
     82 # ------------------------------------------------------------------------------
     83 
     84 #Method static sk_sp<SkImage> MakeRasterData(const SkImageInfo& info, sk_sp<SkData> pixels, size_t rowBytes)
     85 #In Constructors
     86 #Line # creates Image from Image_Info and shared pixels ##
     87 #Populate
     88 
     89 #Example
     90 #Image 3
     91     size_t rowBytes = image->width() * SkColorTypeBytesPerPixel(kRGBA_8888_SkColorType);
     92     sk_sp<SkData> data = SkData::MakeUninitialized(rowBytes * image->height());
     93     SkImageInfo dstInfo = SkImageInfo::MakeN32(image->width(), image->height(),
     94                                                kPremul_SkAlphaType);
     95     image->readPixels(dstInfo, data->writable_data(), rowBytes, 0, 0, SkImage::kAllow_CachingHint);
     96     sk_sp<SkImage> raw = SkImage::MakeRasterData(dstInfo.makeColorType(kRGBA_8888_SkColorType),
     97                                                  data, rowBytes);
     98     canvas->drawImage(image, 0, 0);
     99     canvas->drawImage(raw.get(), 128, 0);
    100 ##
    101 
    102 #SeeAlso MakeRasterCopy MakeFromGenerator
    103 
    104 #Method ##
    105 
    106 # ------------------------------------------------------------------------------
    107 
    108 #Typedef void* ReleaseContext
    109 #Line # parameter type for MakeFromRaster ##
    110 
    111 #Code
    112 #Populate
    113 ##
    114 
    115 Caller data passed to RasterReleaseProc; may be nullptr.
    116 
    117 #SeeAlso MakeFromRaster RasterReleaseProc
    118 
    119 ##
    120 
    121 #Typedef void (*RasterReleaseProc)(const void* pixels, ReleaseContext)
    122 #Line #  parameter type for MakeFromRaster ##
    123 
    124 #Code
    125 #Populate
    126 ##
    127 
    128 Function called when Image no longer shares pixels. ReleaseContext is
    129 provided by caller when Image is created, and may be nullptr.
    130 
    131 #SeeAlso ReleaseContext MakeFromRaster
    132 
    133 ##
    134 
    135 #Method static sk_sp<SkImage> MakeFromRaster(const SkPixmap& pixmap,
    136                                          RasterReleaseProc rasterReleaseProc,
    137                                          ReleaseContext releaseContext)
    138 #In Constructors
    139 #Line # creates Image from Pixmap, with release ##
    140 #Populate
    141 
    142 #Example
    143 #Function
    144 static void releaseProc(const void* pixels, SkImage::ReleaseContext context) {
    145      int* countPtr = static_cast<int*>(context);
    146      *countPtr += 1;
    147 }
    148 ##
    149 
    150 void draw(SkCanvas* canvas) {
    151     SkColor color = 0;
    152     SkPixmap pixmap(SkImageInfo::MakeN32(1, 1, kPremul_SkAlphaType), &color, 4);
    153     int releaseCount = 0;
    154     sk_sp<SkImage> image(SkImage::MakeFromRaster(pixmap, releaseProc, &releaseCount));
    155     SkDebugf("before reset: %d\n", releaseCount);
    156     image.reset();
    157     SkDebugf("after reset: %d\n", releaseCount);
    158 }
    159 #StdOut
    160 before reset: 0
    161 after reset: 1
    162 ##
    163 ##
    164 
    165 #SeeAlso MakeRasterCopy MakeRasterData MakeFromGenerator RasterReleaseProc ReleaseContext
    166 
    167 #Method ##
    168 
    169 # ------------------------------------------------------------------------------
    170 
    171 #Method static sk_sp<SkImage> MakeFromBitmap(const SkBitmap& bitmap)
    172 #In Constructors
    173 #Line # creates Image from Bitmap, sharing or copying pixels ##
    174 #Populate
    175 
    176 #Example
    177 #Description
    178 The first Bitmap is shared; writing to the pixel memory changes the first
    179 Image.
    180 The second Bitmap is marked immutable, and is copied; writing to the pixel
    181 memory does not alter the second Image.
    182 ##
    183 #Height 50
    184     uint8_t storage[][5] = {{ 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 },
    185                             { 0xAC, 0xA8, 0x89, 0xA7, 0x87 },
    186                             { 0x9B, 0xB5, 0xE5, 0x95, 0x46 },
    187                             { 0x90, 0x81, 0xC5, 0x71, 0x33 },
    188                             { 0x75, 0x55, 0x44, 0x40, 0x30 }};
    189     SkImageInfo imageInfo = SkImageInfo::Make(5, 5, kGray_8_SkColorType, kOpaque_SkAlphaType);
    190     SkPixmap pixmap(imageInfo, storage[0], sizeof(storage) / 5);
    191     SkBitmap bitmap;
    192     bitmap.installPixels(pixmap);
    193     sk_sp<SkImage> image1 = SkImage::MakeFromBitmap(bitmap);
    194     bitmap.setImmutable();
    195     sk_sp<SkImage> image2 = SkImage::MakeFromBitmap(bitmap);
    196     *pixmap.writable_addr8(2, 2) = 0x00;
    197     canvas->scale(10, 10);
    198     canvas->drawImage(image1, 0, 0);
    199     canvas->drawImage(image2, 10, 0);
    200 ##
    201 
    202 #SeeAlso MakeFromRaster MakeRasterCopy MakeFromGenerator MakeRasterData
    203 
    204 #Method ##
    205 
    206 # ------------------------------------------------------------------------------
    207 
    208 #Method static sk_sp<SkImage> MakeFromGenerator(std::unique_ptr<SkImageGenerator> imageGenerator,
    209                                             const SkIRect* subset = nullptr)
    210 #In Constructors
    211 #Line # creates Image from a stream of data ##
    212 #Populate
    213 
    214 #Example
    215 #Height 128
    216 #Description
    217 The generator returning Picture cannot be shared; std::move transfers ownership to generated Image.
    218 ##
    219     SkPictureRecorder recorder;
    220     recorder.beginRecording(100, 100)->drawColor(SK_ColorRED);
    221     auto picture = recorder.finishRecordingAsPicture();
    222     auto gen = SkImageGenerator::MakeFromPicture({100, 100}, picture, nullptr, nullptr,
    223                                                  SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB());
    224     sk_sp<SkImage> image = SkImage::MakeFromGenerator(std::move(gen));
    225     canvas->drawImage(image, 0, 0);
    226 ##
    227 
    228 #SeeAlso MakeFromEncoded
    229 
    230 #Method ##
    231 
    232 # ------------------------------------------------------------------------------
    233 
    234 #Method static sk_sp<SkImage> MakeFromEncoded(sk_sp<SkData> encoded, const SkIRect* subset = nullptr)
    235 #In Constructors
    236 #Line # creates Image from encoded data ##
    237 #Populate
    238 
    239 #Example
    240 #Image 3
    241 int x = 0;
    242 for (int quality : { 100, 50, 10, 1} ) {
    243     sk_sp<SkData> encodedData = image->encodeToData(SkEncodedImageFormat::kJPEG, quality);
    244     sk_sp<SkImage> image = SkImage::MakeFromEncoded(encodedData);
    245     canvas->drawImage(image, x, 0);
    246     x += 64;
    247 }
    248 ##
    249 
    250 #SeeAlso MakeFromGenerator
    251 
    252 #Method ##
    253 
    254 # ------------------------------------------------------------------------------
    255 
    256 #Enum CompressionType
    257 #Line # option for MakeFromCompressed ##
    258 #Code
    259 #Populate
    260 ##
    261 
    262 Used to inform MakeFromCompressed which compression method was used on the
    263 input data.
    264 
    265 #Const kETC1_CompressionType 0
    266 #Line # compressed data uses ETC1 compression ##
    267 ##
    268 
    269 #NoExample
    270 ##
    271 
    272 #SeeAlso MakeFromCompressed
    273 
    274 #Enum ##
    275 
    276 #Method static sk_sp<SkImage> MakeFromCompressed(GrContext* context, sk_sp<SkData> data, int width, int height, CompressionType type)
    277 #In Constructors
    278 #Line # creates a GPU-backed Image from compressed data ##
    279 #Populate
    280 
    281 #NoExample
    282 ##
    283 
    284 #SeeAlso MakeFromTexture CompressionType
    285 
    286 #Method ##
    287 
    288 # ------------------------------------------------------------------------------
    289 
    290 #Typedef void (*TextureReleaseProc)(ReleaseContext releaseContext)
    291 #Line # parameter type for MakeFromTexture ##
    292 
    293 #Code
    294 #Populate
    295 ##
    296 
    297 User function called when supplied texture may be deleted.
    298 #SeeAlso MakeFromTexture
    299 ##
    300 
    301 #Method static sk_sp<SkImage> MakeFromTexture(GrContext* context,
    302                                           const GrBackendTexture& backendTexture,
    303                                           GrSurfaceOrigin origin,
    304                                           SkColorType colorType,
    305                                           SkAlphaType alphaType,
    306                                           sk_sp<SkColorSpace> colorSpace)
    307 #In Constructors
    308 #Line # creates Image from GPU_Texture ##
    309 #Populate
    310 
    311 #Example
    312 #Image 3
    313 #Platform gpu
    314 #Height 128
    315 #Description
    316 A back-end texture has been created and uploaded to the GPU outside of this example.
    317 ##
    318 GrContext* context = canvas->getGrContext();
    319 if (!context) {
    320    return;
    321 }
    322 canvas->scale(.25f, .25f);
    323 int x = 0;
    324 for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin } ) {
    325     sk_sp<SkImage> image = SkImage::MakeFromTexture(context, backEndTexture,
    326            origin, kRGBA_8888_SkColorType, kOpaque_SkAlphaType, nullptr);
    327     canvas->drawImage(image, x, 0);
    328 x += 512;
    329 }
    330 ##
    331 
    332 #SeeAlso MakeFromAdoptedTexture SkSurface::MakeFromBackendTexture
    333 
    334 #Method ##
    335 
    336 # ------------------------------------------------------------------------------
    337 
    338 #Method static sk_sp<SkImage> MakeFromTexture(GrContext* context,
    339                                           const GrBackendTexture& backendTexture,
    340                                           GrSurfaceOrigin origin,
    341                                           SkColorType colorType,
    342                                           SkAlphaType alphaType,
    343                                           sk_sp<SkColorSpace> colorSpace,
    344                                           TextureReleaseProc textureReleaseProc,
    345                                           ReleaseContext releaseContext)
    346 #Populate
    347 
    348 #Example
    349 #Description
    350 textureReleaseProc may be called at some later point in time. In this example,
    351 textureReleaseProc has no effect on the drawing.
    352 ##
    353 #Platform gpu
    354 #Image 4
    355 GrContext* context = canvas->getGrContext();
    356 if (!context) {
    357    return;
    358 }
    359 auto debugster = [](SkImage::ReleaseContext releaseContext) -> void {
    360    *((int *) releaseContext) += 128;
    361 };
    362 int x = 0, y = 0;
    363 for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin } ) {
    364     sk_sp<SkImage> image = SkImage::MakeFromTexture(context, backEndTexture,
    365            origin, kRGBA_8888_SkColorType, kOpaque_SkAlphaType, nullptr, debugster, &x);
    366     canvas->drawImage(image, x, y);
    367     y += 128;
    368 }
    369 ##
    370 
    371 #SeeAlso MakeFromAdoptedTexture SkSurface::MakeFromBackendTexture
    372 
    373 #Method ##
    374 
    375 # ------------------------------------------------------------------------------
    376 
    377 #Method static sk_sp<SkImage> MakeCrossContextFromEncoded(GrContext* context, sk_sp<SkData> data,
    378                                                       bool buildMips,
    379                                                       SkColorSpace* dstColorSpace,
    380                                                       bool limitToMaxTextureSize = false)
    381 #In Constructors
    382 #Line # creates Image from encoded data, and uploads to GPU ##
    383 #Populate
    384 
    385 #Example
    386 #Image 4
    387 #Height 64
    388 GrContext* context = canvas->getGrContext();
    389 sk_sp<SkData> encodedData = image->encodeToData(SkEncodedImageFormat::kJPEG, 100);
    390 sk_sp<SkImage> image = SkImage::MakeCrossContextFromEncoded(context,
    391                                                             encodedData, false, nullptr);
    392 canvas->drawImage(image, 0, 0);
    393 ##
    394 
    395 #SeeAlso MakeCrossContextFromPixmap
    396 
    397 #Method ##
    398 
    399 # ------------------------------------------------------------------------------
    400 
    401 #Method static sk_sp<SkImage> MakeCrossContextFromPixmap(GrContext* context, const SkPixmap& pixmap,
    402                                                       bool buildMips,
    403                                                       SkColorSpace* dstColorSpace,
    404                                                       bool limitToMaxTextureSize = false)
    405 #In Constructors
    406 #Line # creates Image from Pixmap, and uploads to GPU ##
    407 #Populate
    408 
    409 #Example
    410 #Image 4
    411 #Height 64
    412 GrContext* context = canvas->getGrContext();
    413 SkPixmap pixmap;
    414 if (source.peekPixels(&pixmap)) {
    415     sk_sp<SkImage> image = SkImage::MakeCrossContextFromPixmap(context, pixmap,
    416                                                                false, nullptr);
    417     canvas->drawImage(image, 0, 0);
    418 }
    419 ##
    420 
    421 #SeeAlso MakeCrossContextFromEncoded
    422 
    423 #Method ##
    424 
    425 # ------------------------------------------------------------------------------
    426 
    427 #Method static sk_sp<SkImage> MakeFromAdoptedTexture(GrContext* context,
    428                                                  const GrBackendTexture& backendTexture,
    429                                                  GrSurfaceOrigin surfaceOrigin,
    430                                                  SkColorType colorType,
    431                                                  SkAlphaType alphaType = kPremul_SkAlphaType,
    432                                                  sk_sp<SkColorSpace> colorSpace = nullptr)
    433 #In Constructors
    434 #Line # creates Image from GPU_Texture, managed internally ##
    435 #Populate
    436 
    437 #Example
    438 #Image 5
    439 #Platform gpu
    440    if (!canvas->getGrContext()) {
    441        return;
    442    }
    443    canvas->scale(.5f, .5f);
    444    canvas->clear(0x7f3f5f7f);
    445    int x = 0, y = 0;
    446    for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin } ) {
    447        for (auto alpha : { kOpaque_SkAlphaType, kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
    448            sk_sp<SkImage> image = SkImage::MakeFromAdoptedTexture(canvas->getGrContext(),
    449                                                                   backEndTexture, origin,
    450                                                                   kRGBA_8888_SkColorType, alpha);
    451            canvas->drawImage(image, x, y);
    452            x += 160;
    453        }
    454        x -= 160 * 3;
    455        y += 256;
    456    }
    457 ##
    458 
    459 #SeeAlso MakeFromTexture MakeFromYUVTexturesCopy
    460 
    461 #Method ##
    462 
    463 # ------------------------------------------------------------------------------
    464 
    465 #Method static sk_sp<SkImage> MakeFromYUVATexturesCopy(GrContext* context,
    466                                                    SkYUVColorSpace yuvColorSpace,
    467                                                    const GrBackendTexture yuvaTextures[],
    468                                                    const SkYUVAIndex yuvaIndices[4],
    469                                                    SkISize imageSize,
    470                                                    GrSurfaceOrigin imageOrigin,
    471                                                    sk_sp<SkColorSpace> imageColorSpace = nullptr)
    472 #In Constructor
    473 #Line # creates Image from YUV_ColorSpace data ##
    474 #Populate
    475 
    476 #NoExample
    477 ##
    478 
    479 #SeeAlso MakeFromYUVATexturesCopyWithExternalBackend MakeFromYUVATextures
    480 
    481 #Method ##
    482 
    483 #Method static sk_sp<SkImage> MakeFromYUVATextures(GrContext* context,
    484                                                SkYUVColorSpace yuvColorSpace,
    485                                                const GrBackendTexture yuvaTextures[],
    486                                                const SkYUVAIndex yuvaIndices[4],
    487                                                SkISize imageSize,
    488                                                GrSurfaceOrigin imageOrigin,
    489                                                sk_sp<SkColorSpace> imageColorSpace = nullptr);
    490 
    491 #In Constructor
    492 #Line # creates Image from YUV_ColorSpace data ##
    493 #Populate
    494 
    495 #NoExample
    496 ##
    497 
    498 #SeeAlso MakeFromYUVATexturesCopy MakeFromYUVATexturesCopyWithExternalBackend
    499 
    500 #Method ##
    501 
    502 #Method static sk_sp<SkImage> MakeFromYUVAPixmaps(
    503                                                GrContext* context,
    504                                                SkYUVColorSpace yuvColorSpace,
    505                                                const SkPixmap yuvaPixmaps[],
    506                                                const SkYUVAIndex yuvaIndices[4],
    507                                                SkISize imageSize,
    508                                                GrSurfaceOrigin imageOrigin,
    509                                                bool buildMips,
    510                                                bool limitToMaxTextureSize = false,
    511                                                sk_sp<SkColorSpace> imageColorSpace = nullptr);
    512 
    513 #In Constructor
    514 #Line # creates Image from YUV_ColorSpace data ##
    515 #Populate
    516 
    517 #NoExample
    518 ##
    519 
    520 #SeeAlso MakeFromYUVATextures
    521 
    522 #Method ##
    523 
    524 # ------------------------------------------------------------------------------
    525 
    526 #Method static sk_sp<SkImage> MakeFromYUVATexturesCopyWithExternalBackend(
    527             GrContext* context,
    528             SkYUVColorSpace yuvColorSpace,
    529             const GrBackendTexture yuvaTextures[],
    530             const SkYUVAIndex yuvaIndices[4],
    531             SkISize imageSize,
    532             GrSurfaceOrigin imageOrigin,
    533             const GrBackendTexture& backendTexture,
    534             sk_sp<SkColorSpace> imageColorSpace = nullptr)
    535 #In Constructor
    536 #Line # creates Image from planar YUV_ColorSpace, stored in texture ##
    537 #Populate
    538 
    539 #NoExample
    540 ##
    541 
    542 #SeeAlso MakeFromYUVATexturesCopy MakeFromYUVATextures
    543 
    544 #Method ##
    545 
    546 #Method static sk_sp<SkImage> MakeFromYUVTexturesCopy(GrContext* context, SkYUVColorSpace yuvColorSpace,
    547                                                   const GrBackendTexture yuvTextures[3],
    548                                                   GrSurfaceOrigin imageOrigin,
    549                                                   sk_sp<SkColorSpace> imageColorSpace = nullptr)
    550 #In Constructors
    551 #Line # creates Image from YUV_ColorSpace data in three planes ##
    552 #Populate
    553 
    554 #NoExample
    555 ##
    556 
    557 #SeeAlso MakeFromYUVTexturesCopyWithExternalBackend MakeFromNV12TexturesCopy MakeFromYUVATexturesCopy
    558 
    559 #Method ##
    560 
    561 # ------------------------------------------------------------------------------
    562 
    563 #Method static sk_sp<SkImage> MakeFromYUVTexturesCopyWithExternalBackend(
    564         GrContext* context, SkYUVColorSpace yuvColorSpace,
    565         const GrBackendTexture yuvTextures[3], GrSurfaceOrigin imageOrigin,
    566         const GrBackendTexture& backendTexture, sk_sp<SkColorSpace> imageColorSpace = nullptr);
    567 #In Constructors
    568 #Line # creates Image from planar YUV_ColorSpace, stored in texture ##
    569 #Populate
    570 
    571 #NoExample
    572 ##
    573 
    574 #SeeAlso MakeFromYUVTexturesCopy MakeFromNV12TexturesCopy MakeFromYUVATexturesCopyWithExternalBackend
    575 
    576 #Method ##
    577 
    578 # ------------------------------------------------------------------------------
    579 
    580 #Method static sk_sp<SkImage> MakeFromNV12TexturesCopy(GrContext* context,
    581                                                    SkYUVColorSpace yuvColorSpace,
    582                                                    const GrBackendTexture nv12Textures[2],
    583                                                    GrSurfaceOrigin imageOrigin,
    584                                                    sk_sp<SkColorSpace> imageColorSpace = nullptr)
    585 #In Constructors
    586 #Line # creates Image from YUV_ColorSpace data in three planes ##
    587 #Populate
    588 
    589 #NoExample
    590 ##
    591 
    592 #SeeAlso MakeFromNV12TexturesCopyWithExternalBackend MakeFromYUVTexturesCopy MakeFromYUVATexturesCopy
    593 
    594 #Method ##
    595 
    596 #Method static sk_sp<SkImage> MakeFromNV12TexturesCopyWithExternalBackend(
    597             GrContext* context,
    598             SkYUVColorSpace yuvColorSpace,
    599             const GrBackendTexture nv12Textures[2],
    600             GrSurfaceOrigin imageOrigin,
    601             const GrBackendTexture& backendTexture,
    602             sk_sp<SkColorSpace> imageColorSpace = nullptr);
    603 #In Constructors
    604 #Line # creates Image from planar YUV_ColorSpace, stored in texture ##
    605 #Populate
    606 
    607 #NoExample
    608 ##
    609 
    610 #SeeAlso MakeFromNV12TexturesCopy MakeFromYUVTexturesCopy MakeFromYUVATexturesCopyWithExternalBackend
    611 
    612 #Method ##
    613 
    614 # ------------------------------------------------------------------------------
    615 
    616 # currently uncalled by any test or client ##
    617 #Bug 7424
    618 
    619 #EnumClass BitDepth
    620 #Line # options for MakeFromPicture ##
    621 #Code
    622 #Populate
    623 ##
    624 
    625 #Const kU8 0
    626 #Line # uses 8-bit unsigned int per Color component ##
    627 Use 8 bits per ARGB component using unsigned integer format.
    628 ##
    629 #Const kF16 1
    630 #Line # uses 16-bit float per Color component ##
    631 Use 16 bits per ARGB component using half-precision floating point format.
    632 ##
    633 
    634 #NoExample
    635 ##
    636 
    637 #SeeAlso MakeFromPicture
    638 
    639 #EnumClass ##
    640 
    641 # ------------------------------------------------------------------------------
    642 
    643 #Method static sk_sp<SkImage> MakeFromPicture(sk_sp<SkPicture> picture, const SkISize& dimensions,
    644                                           const SkMatrix* matrix, const SkPaint* paint,
    645                                           BitDepth bitDepth,
    646                                           sk_sp<SkColorSpace> colorSpace)
    647 #In Constructors
    648 #Line # creates Image from Picture ##
    649 #Populate
    650 
    651 #Example
    652     SkPaint paint;
    653     SkPictureRecorder recorder;
    654     SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
    655     for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
    656         paint.setColor(color);
    657         recordingCanvas->drawRect({10, 10, 30, 40}, paint);
    658         recordingCanvas->translate(10, 10);
    659         recordingCanvas->scale(1.2f, 1.4f);
    660     }
    661     sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
    662     int x = 0, y = 0;
    663     for (auto alpha : { 70, 140, 210 } ) {
    664         paint.setAlpha(alpha);
    665         auto srgbColorSpace = SkColorSpace::MakeSRGB();
    666         sk_sp<SkImage> image = SkImage::MakeFromPicture(playback, {50, 50}, nullptr, &paint,
    667                                                         SkImage::BitDepth::kU8, srgbColorSpace);
    668         canvas->drawImage(image, x, y);
    669         x += 70; y += 70;
    670     }
    671 ##
    672 
    673 #SeeAlso SkCanvas::drawPicture
    674 
    675 #Method ##
    676 
    677 # ------------------------------------------------------------------------------
    678 
    679 #Method static sk_sp<SkImage> MakeFromAHardwareBuffer(
    680         AHardwareBuffer* hardwareBuffer,
    681         SkAlphaType alphaType = kPremul_SkAlphaType,
    682         sk_sp<SkColorSpace> colorSpace = nullptr,
    683         GrSurfaceOrigin surfaceOrigin = kTopLeft_GrSurfaceOrigin)
    684 #In Constructors
    685 #Line # creates Image from Android hardware buffer ##
    686 #Populate
    687 
    688 #NoExample
    689 ##
    690 
    691 #SeeAlso MakeFromRaster
    692 
    693 #Method ##
    694 
    695 # ------------------------------------------------------------------------------
    696 #Subtopic Property
    697 #Line # values and attributes ##
    698 ##
    699 
    700 #Method int width() const
    701 #In Property
    702 #Line # returns pixel column count ##
    703 #Populate
    704 
    705 #Example
    706 #Image 4
    707 #Height 96
    708    canvas->translate(10, 10);
    709    canvas->drawImage(image, 0, 0);
    710    canvas->translate(0, image->height());
    711    SkPaint paint;
    712    canvas->drawLine(0, 10, image->width(), 10, paint);
    713    canvas->drawString("width", image->width() / 2 - 15, 25, paint);
    714 ##
    715 
    716 #SeeAlso dimensions() height()
    717 
    718 #Method ##
    719 
    720 # ------------------------------------------------------------------------------
    721 
    722 #Method int height() const
    723 #In Property
    724 #Line # returns pixel row count ##
    725 #Populate
    726 
    727 #Example
    728 #Image 4
    729 #Height 96
    730    canvas->translate(10, 10);
    731    canvas->drawImage(image, 0, 0);
    732    canvas->translate(image->width(), 0);
    733    SkPaint paint;
    734    canvas->drawLine(10, 0, 10, image->height(), paint);
    735    canvas->drawString("height", 34, image->height() / 2, paint);
    736 ##
    737 
    738 #SeeAlso dimensions() width()
    739 
    740 #Method ##
    741 
    742 # ------------------------------------------------------------------------------
    743 
    744 #Method SkISize dimensions() const
    745 #In Property
    746 #Line # returns width() and height() ##
    747 #Populate
    748 
    749 #Example
    750 #Image 4
    751     SkISize dimensions = image->dimensions();
    752     SkIRect bounds = image->bounds();
    753     SkIRect dimensionsAsBounds = SkIRect::MakeSize(dimensions);
    754     SkDebugf("dimensionsAsBounds %c= bounds\n", dimensionsAsBounds == bounds ? '=' : '!');
    755 #StdOut
    756 dimensionsAsBounds == bounds
    757 ##
    758 ##
    759 
    760 #SeeAlso height() width() bounds()
    761 
    762 #Method ##
    763 
    764 # ------------------------------------------------------------------------------
    765 
    766 #Method SkIRect bounds() const
    767 #In Property
    768 #Line # returns width() and height() as Rectangle ##
    769 #Populate
    770 
    771 #Example
    772 #Height 128
    773 #Image 4
    774     SkIRect bounds = image->bounds();
    775     for (int x : { 0, bounds.width() } ) {
    776         for (int y : { 0, bounds.height() } ) {
    777             canvas->drawImage(image, x, y);
    778         }
    779     }
    780 ##
    781 
    782 #SeeAlso dimensions()
    783 
    784 #Method ##
    785 
    786 # ------------------------------------------------------------------------------
    787 
    788 #Method uint32_t uniqueID() const
    789 #In Property
    790 #Line # returns identifier for Image ##
    791 #Populate
    792 
    793 #Example
    794 #Image 5
    795 #Height 156
    796  sk_sp<SkImage> subset = image->makeSubset({10, 20, 90, 100});
    797  canvas->drawImage(image, 0, 0);
    798  canvas->drawImage(subset, 128, 0);
    799  SkPaint paint;
    800  SkString s;
    801  s.printf("original id: %d", image->uniqueID());
    802  canvas->drawString(s, 20, image->height() + 20, paint);
    803  s.printf("subset id: %d", subset->uniqueID());
    804  canvas->drawString(s, 148, subset->height() + 20, paint);
    805 ##
    806 
    807 #SeeAlso isLazyGenerated
    808 
    809 #Method ##
    810 
    811 # ------------------------------------------------------------------------------
    812 
    813 #Method SkAlphaType alphaType() const
    814 #In Property
    815 #Line # returns Alpha_Type ##
    816 Returns Alpha_Type, one of: #list_of_alpha_types#.
    817 
    818 Alpha_Type returned was a parameter to an Image constructor,
    819 or was parsed from encoded data.
    820 
    821 #Return Alpha_Type in Image ##
    822 
    823 #Example
    824 #Image 4
    825 #Height 96
    826   const char* alphaTypeStr[] = { "Unknown", "Opaque", "Premul", "Unpremul" };
    827   SkAlphaType alphaType = image->alphaType();
    828   canvas->drawImage(image, 16, 0);
    829   canvas->drawString(alphaTypeStr[(int) alphaType], 20, image->height() + 20, SkPaint());
    830 ##
    831 
    832 #SeeAlso SkImageInfo::alphaType
    833 
    834 #Method ##
    835 
    836 # ------------------------------------------------------------------------------
    837 
    838 #Method SkColorType colorType() const
    839 #In Property
    840 #Line # returns Color_Type ##
    841 #Populate
    842 
    843 #Example
    844 #Image 4
    845 #Height 96
    846     const char* colors[] = { "Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
    847                              "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16" };
    848     SkColorType colorType = image->colorType();
    849     canvas->drawImage(image, 16, 0);
    850     canvas->drawString(colors[(int) colorType], 20, image->height() + 20, SkPaint());
    851 ##
    852 
    853 #SeeAlso SkImageInfo::colorType
    854 
    855 #Method ##
    856 
    857 # ------------------------------------------------------------------------------
    858 
    859 #Method SkColorSpace* colorSpace() const
    860 #In Property
    861 #Line # returns Color_Space ##
    862 #Populate
    863 
    864 #Example
    865 #Image 3
    866 #Set sRGB
    867     SkPixmap pixmap;
    868     source.peekPixels(&pixmap);
    869     canvas->scale(.25f, .25f);
    870     int y = 0;
    871     for (auto gamma : { SkNamedTransferFn::kLinear,
    872                         SkNamedTransferFn::kSRGB } ) {
    873         int x = 0;
    874         sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeRGB(gamma, SkNamedGamut::kSRGB);
    875         for (int index = 0; index < 2; ++index) {
    876             pixmap.setColorSpace(colorSpace);
    877             sk_sp<SkImage> image = SkImage::MakeRasterCopy(pixmap);
    878             canvas->drawImage(image, x, y);
    879             colorSpace = image->colorSpace()->makeColorSpin();
    880             x += 512;
    881         }
    882         y += 512;
    883     }
    884 ##
    885 
    886 #SeeAlso refColorSpace makeColorSpace
    887 
    888 #Method ##
    889 
    890 # ------------------------------------------------------------------------------
    891 
    892 #Method sk_sp<SkColorSpace> refColorSpace() const
    893 #In Property
    894 #Line # returns Image_Info Color_Space ##
    895 #Populate
    896 
    897 #Example
    898 #Image 3
    899 #Set sRGB
    900     SkPixmap pixmap;
    901     source.peekPixels(&pixmap);
    902     canvas->scale(.25f, .25f);
    903     int y = 0;
    904     for (auto gamma : { SkNamedTransferFn::kLinear,
    905                         SkNamedTransferFn::kSRGB } ) {
    906         int x = 0;
    907         sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeRGB(gamma, SkNamedGamut::kSRGB);
    908         for (int index = 0; index < 2; ++index) {
    909             pixmap.setColorSpace(colorSpace);
    910             sk_sp<SkImage> image = SkImage::MakeRasterCopy(pixmap);
    911             canvas->drawImage(image, x, y);
    912             colorSpace = image->refColorSpace()->makeColorSpin();
    913             x += 512;
    914         }
    915         y += 512;
    916     }
    917 ##
    918 
    919 #SeeAlso colorSpace makeColorSpace
    920 
    921 #Method ##
    922 
    923 # ------------------------------------------------------------------------------
    924 
    925 #Method bool isAlphaOnly() const
    926 #In Property
    927 #Line # returns if pixels represent a transparency mask ##
    928 #Populate
    929 
    930 #Example
    931     uint8_t pmColors = 0;
    932     sk_sp<SkImage> image = SkImage::MakeRasterCopy({SkImageInfo::MakeA8(1, 1), &pmColors, 1});
    933     SkDebugf("alphaOnly = %s\n", image->isAlphaOnly() ? "true" : "false");
    934 #StdOut
    935 alphaOnly = true
    936 ##
    937 ##
    938 
    939 #SeeAlso alphaType isOpaque
    940 
    941 #Method ##
    942 
    943 # ------------------------------------------------------------------------------
    944 
    945 #Method bool isOpaque() const
    946 #In Property
    947 #Line # returns if Alpha_Type is kOpaque_SkAlphaType ##
    948 #Populate
    949 
    950 #Example
    951     auto check_isopaque = [](const SkImageInfo& imageInfo) -> void {
    952         auto surface(SkSurface::MakeRaster(imageInfo));
    953         auto image(surface->makeImageSnapshot());
    954         SkDebugf("isOpaque = %s\n", image->isOpaque() ? "true" : "false");
    955     };
    956 
    957     check_isopaque(SkImageInfo::MakeN32Premul(5, 5));
    958     check_isopaque(SkImageInfo::MakeN32(5, 5, kOpaque_SkAlphaType));
    959 #StdOut
    960 isOpaque = false
    961 isOpaque = true
    962 ##
    963 ##
    964 
    965 #SeeAlso alphaType isAlphaOnly
    966 
    967 #Method ##
    968 
    969 # ------------------------------------------------------------------------------
    970 
    971 #Method sk_sp<SkShader> makeShader(SkShader::TileMode tileMode1, SkShader::TileMode tileMode2,
    972                                const SkMatrix* localMatrix = nullptr) const
    973 #In Constructors
    974 #Line # creates Shader, Paint element that can tile Image ##
    975 #Populate
    976 
    977 #Example
    978 #Image 4
    979 SkMatrix matrix;
    980 matrix.setRotate(45);
    981 SkPaint paint;
    982 paint.setShader(image->makeShader(SkShader::kRepeat_TileMode, SkShader::kMirror_TileMode,
    983                                   &matrix));
    984 canvas->drawPaint(paint);
    985 ##
    986 
    987 #SeeAlso scalePixels
    988 
    989 #Method ##
    990 
    991 # ------------------------------------------------------------------------------
    992 
    993 #Method sk_sp<SkShader> makeShader(const SkMatrix* localMatrix = nullptr) const
    994 #Populate
    995 
    996 #Example
    997 #Image 5
    998 SkMatrix matrix;
    999 matrix.setRotate(45);
   1000 matrix.postTranslate(125, 30);
   1001 SkPaint paint;
   1002 paint.setShader(image->makeShader(&matrix));
   1003 canvas->drawPaint(paint);
   1004 ##
   1005 
   1006 #SeeAlso scalePixels
   1007 
   1008 #Method ##
   1009 
   1010 # ------------------------------------------------------------------------------
   1011 #Subtopic Pixels
   1012 #Line # read and write pixel values ##
   1013 ##
   1014 
   1015 #Method bool peekPixels(SkPixmap* pixmap) const
   1016 #In Pixels
   1017 #Line # returns Pixmap if possible ##
   1018 #Populate
   1019 
   1020 #Example
   1021     SkBitmap bitmap;
   1022     bitmap.allocPixels(SkImageInfo::MakeN32Premul(12, 11));
   1023     SkCanvas offscreen(bitmap);
   1024     offscreen.clear(SK_ColorWHITE);
   1025     SkPaint paint;
   1026     offscreen.drawString("%", 1, 10, paint);
   1027     sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
   1028     SkPixmap pixmap;
   1029     if (image->peekPixels(&pixmap)) {
   1030         const SkPMColor* pixels = pixmap.addr32();
   1031         SkPMColor pmWhite = pixels[0];
   1032         for (int y = 0; y < image->height(); ++y) {
   1033             for (int x = 0; x < image->width(); ++x) {
   1034                 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
   1035             }
   1036             SkDebugf("\n");
   1037         }
   1038     }
   1039 #StdOut
   1040 ------------
   1041 --xx----x---
   1042 -x--x--x----
   1043 -x--x--x----
   1044 -x--x-x-----
   1045 --xx-xx-xx--
   1046 -----x-x--x-
   1047 ----x--x--x-
   1048 ----x--x--x-
   1049 ---x----xx--
   1050 ------------
   1051 ##
   1052 ##
   1053 
   1054 #SeeAlso readPixels
   1055 
   1056 #Method ##
   1057 
   1058 # ------------------------------------------------------------------------------
   1059 
   1060 #Method bool isTextureBacked() const
   1061 #In Property
   1062 #Line # returns if Image was created from GPU_Texture ##
   1063 #Populate
   1064 
   1065 #Example
   1066 #Image 5
   1067 #Platform gpu
   1068 auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {
   1069     if (nullptr == image) {
   1070         return;
   1071     }
   1072     SkPaint paint;
   1073     paint.setAntiAlias(true);
   1074     canvas->drawImage(image, 0, 0);
   1075     canvas->drawString(label, 30, image->height() / 4, paint);
   1076     canvas->drawString(image->isTextureBacked() ? "is GPU texture" : "not GPU texture",
   1077                        20, image->height() * 3 / 4, paint);
   1078 };
   1079 sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
   1080 sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
   1081                             kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
   1082                             kOpaque_SkAlphaType, nullptr));
   1083 drawImage(image, "image");
   1084 canvas->translate(image->width(), 0);
   1085 drawImage(bitmapImage, "source");
   1086 canvas->translate(-image->width(), image->height());
   1087 drawImage(textureImage, "backEndTexture");
   1088 ##
   1089 
   1090 #SeeAlso MakeFromTexture isValid
   1091 
   1092 #Method ##
   1093 
   1094 # ------------------------------------------------------------------------------
   1095 
   1096 #Method bool isValid(GrContext* context) const
   1097 #In Property
   1098 #Line # returns if Image can draw to Raster_Surface or GPU_Context ##
   1099 #Populate
   1100 
   1101 #Example
   1102 #Image 5
   1103 #Platform gpu
   1104 auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {
   1105     if (nullptr == image) {
   1106         return;
   1107     }
   1108     SkPaint paint;
   1109     paint.setAntiAlias(true);
   1110     canvas->drawImage(image, 0, 0);
   1111     canvas->drawString(label, image->width() / 2, image->height() / 4, paint);
   1112     if (canvas->getGrContext()) {
   1113         canvas->drawString(image->isValid(canvas->getGrContext()) ? "is valid on GPU" :
   1114                 "not valid on GPU", 20, image->height() * 5 / 8, paint);
   1115     }
   1116     canvas->drawString(image->isValid(nullptr) ? "is valid on CPU" :
   1117             "not valid on CPU", 20, image->height() * 7 / 8, paint);
   1118 };
   1119 sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
   1120 sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
   1121                             kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
   1122                             kOpaque_SkAlphaType, nullptr));
   1123 drawImage(image, "image");
   1124 canvas->translate(image->width(), 0);
   1125 drawImage(bitmapImage, "source");
   1126 canvas->translate(-image->width(), image->height());
   1127 drawImage(textureImage, "backEndTexture");
   1128 ##
   1129 
   1130 #SeeAlso isTextureBacked isLazyGenerated
   1131 
   1132 #Method ##
   1133 
   1134 # ------------------------------------------------------------------------------
   1135 
   1136 #Method GrBackendTexture getBackendTexture(bool flushPendingGrContextIO,
   1137                                            GrSurfaceOrigin* origin = nullptr) const
   1138 #In Property
   1139 #Line # returns GPU reference to Image as texture ##
   1140 #Populate
   1141 
   1142 #Example
   1143 #Image 3
   1144 #Platform gpu
   1145     GrContext* grContext = canvas->getGrContext();
   1146     if (!grContext) {
   1147         canvas->drawString("GPU only!", 20, 40, SkPaint());
   1148         return;
   1149     }
   1150     sk_sp<SkImage> imageFromBackend = SkImage::MakeFromAdoptedTexture(grContext, backEndTexture,
   1151             kBottomLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
   1152     GrBackendTexture textureFromImage = imageFromBackend->getBackendTexture(false);
   1153     if (!textureFromImage.isValid()) {
   1154         return;
   1155     }
   1156     sk_sp<SkImage> imageFromTexture = SkImage::MakeFromAdoptedTexture(grContext, textureFromImage,
   1157             kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
   1158     canvas->drawImage(imageFromTexture, 0, 0);
   1159     canvas->drawImage(imageFromBackend, 128, 128);
   1160 ##
   1161 
   1162 #SeeAlso MakeFromTexture isTextureBacked
   1163 
   1164 #Method ##
   1165 
   1166 # ------------------------------------------------------------------------------
   1167 
   1168 #Enum CachingHint
   1169 #Line # options for readPixels and scalePixels ##
   1170 #Code
   1171 #Populate
   1172 ##
   1173 
   1174 CachingHint selects whether Skia may internally cache Bitmaps generated by
   1175 decoding Image, or by copying Image from GPU to CPU. The default behavior
   1176 allows caching Bitmaps.
   1177 
   1178 Choose kDisallow_CachingHint if Image pixels are to be used only once, or
   1179 if Image pixels reside in a cache outside of Skia, or to reduce memory pressure.
   1180 
   1181 Choosing kAllow_CachingHint does not ensure that pixels will be cached.
   1182 Image pixels may not be cached if memory requirements are too large or
   1183 pixels are not accessible.
   1184 
   1185 #Const kAllow_CachingHint 0
   1186 #Line # allows internally caching decoded and copied pixels ##
   1187 ##
   1188 #Const kDisallow_CachingHint 1
   1189 #Line # disallows internally caching decoded and copied pixels ##
   1190 ##
   1191 
   1192 #NoExample
   1193 ##
   1194 
   1195 #SeeAlso readPixels scalePixels
   1196 
   1197 #Enum ##
   1198 
   1199 # ------------------------------------------------------------------------------
   1200 
   1201 #Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
   1202                     int srcX, int srcY, CachingHint cachingHint = kAllow_CachingHint) const
   1203 #In Pixels
   1204 #Line # copies and converts pixels ##
   1205 
   1206 Copies Rect of pixels from Image to dstPixels. Copy starts at offset (srcX, srcY),
   1207 and does not exceed Image (width(), height()).
   1208 
   1209 dstInfo specifies width, height, Color_Type, Alpha_Type, and Color_Space of
   1210 destination. dstRowBytes specifics the gap from one destination row to the next.
   1211 Returns true if pixels are copied. Returns false if:
   1212 #List
   1213 # dstInfo has no address ##
   1214 # dstRowBytes is less than dstInfo.minRowBytes() ##
   1215 # Pixel_Ref is nullptr ##
   1216 ##
   1217 
   1218 Pixels are copied only if pixel conversion is possible. If Image Color_Type is
   1219 kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType() must match.
   1220 If Image Color_Type is kGray_8_SkColorType, dstInfo.colorSpace() must match.
   1221 If Image Alpha_Type is kOpaque_SkAlphaType, dstInfo.alphaType() must
   1222 match. If Image Color_Space is nullptr, dstInfo.colorSpace() must match. Returns
   1223 false if pixel conversion is not possible.
   1224 
   1225 srcX and srcY may be negative to copy only top or left of source. Returns
   1226 false if width() or height() is zero or negative.
   1227 Returns false if #Formula # abs(srcX) >= Image width() ##, or if #Formula # abs(srcY) >= Image height() ##.
   1228 
   1229 If cachingHint is kAllow_CachingHint, pixels may be retained locally.
   1230 If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
   1231 
   1232 #Param dstInfo  destination width, height, Color_Type, Alpha_Type, Color_Space ##
   1233 #Param dstPixels  destination pixel storage ##
   1234 #Param dstRowBytes  destination row length ##
   1235 #Param srcX  column index whose absolute value is less than width() ##
   1236 #Param srcY  row index whose absolute value is less than height() ##
   1237 #Param cachingHint  one of: kAllow_CachingHint, kDisallow_CachingHint ##
   1238 
   1239 #Return true if pixels are copied to dstPixels ##
   1240 
   1241 #Example
   1242 #Image 3
   1243     canvas->scale(.5f, .5f);
   1244     const int width = 32;
   1245     const int height = 32;
   1246     std::vector<int32_t> dstPixels;
   1247     dstPixels.resize(height * width * 4);
   1248     SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
   1249     for (int y = 0; y < 512; y += height ) {
   1250         for (int x = 0; x < 512; x += width ) {
   1251             if (image->readPixels(info, &dstPixels.front(), width * 4, x, y)) {
   1252                 SkPixmap dstPixmap(info, &dstPixels.front(), width * 4);
   1253                 SkBitmap bitmap;
   1254                 bitmap.installPixels(dstPixmap);
   1255                 canvas->drawBitmap(bitmap, 0, 0);
   1256             }
   1257             canvas->translate(48, 0);
   1258         }
   1259         canvas->translate(-16 * 48, 48);
   1260     }
   1261 ##
   1262 
   1263 #SeeAlso scalePixels SkBitmap::readPixels SkPixmap::readPixels SkCanvas::readPixels SkSurface::readPixels
   1264 
   1265 #Method ##
   1266 
   1267 # ------------------------------------------------------------------------------
   1268 
   1269 #Method bool readPixels(const SkPixmap& dst, int srcX, int srcY,
   1270                     CachingHint cachingHint = kAllow_CachingHint) const
   1271 
   1272 Copies a Rect of pixels from Image to dst. Copy starts at (srcX, srcY), and
   1273 does not exceed Image (width(), height()).
   1274 
   1275 dst specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
   1276 and row bytes of destination. dst.rowBytes() specifics the gap from one destination
   1277 row to the next. Returns true if pixels are copied. Returns false if:
   1278 #List
   1279 # dst pixel storage equals nullptr ##
   1280 # dst.rowBytes() is less than SkImageInfo::minRowBytes ##
   1281 # Pixel_Ref is nullptr ##
   1282 ##
   1283 
   1284 Pixels are copied only if pixel conversion is possible. If Image Color_Type is
   1285 kGray_8_SkColorType, or kAlpha_8_SkColorType; dst.colorType() must match.
   1286 If Image Color_Type is kGray_8_SkColorType, dst.colorSpace() must match.
   1287 If Image Alpha_Type is kOpaque_SkAlphaType, dst.alphaType() must
   1288 match. If Image Color_Space is nullptr, dst.colorSpace() must match. Returns
   1289 false if pixel conversion is not possible.
   1290 
   1291 srcX and srcY may be negative to copy only top or left of source. Returns
   1292 false if width() or height() is zero or negative.
   1293 Returns false if #Formula # abs(srcX) >= Image width() ##, or if #Formula # abs(srcY) >= Image height() ##.
   1294 
   1295 If cachingHint is kAllow_CachingHint, pixels may be retained locally.
   1296 If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
   1297 
   1298 #Param dst  destination Pixmap: Image_Info, pixels, row bytes ##
   1299 #Param srcX  column index whose absolute value is less than width() ##
   1300 #Param srcY  row index whose absolute value is less than height() ##
   1301 #Param cachingHint  one of: kAllow_CachingHint, kDisallow_CachingHint ##
   1302 
   1303 #Return true if pixels are copied to dst ##
   1304 
   1305 #Example
   1306 #Image 3
   1307     std::vector<int32_t> srcPixels;
   1308     int rowBytes = image->width() * 4;
   1309     int quarterWidth = image->width() / 4;
   1310     int quarterHeight = image->height() / 4;
   1311     srcPixels.resize(image->height() * rowBytes);
   1312     for (int y = 0; y < 4; ++y) {
   1313         for (int x = 0; x < 4; ++x) {
   1314             SkPixmap pixmap(SkImageInfo::MakeN32Premul(quarterWidth, quarterHeight),
   1315                     &srcPixels.front() + x * image->height() * quarterWidth +
   1316                     y * quarterWidth, rowBytes);
   1317             image->readPixels(pixmap, x * quarterWidth, y * quarterHeight);
   1318         }
   1319     }
   1320     canvas->scale(.5f, .5f);
   1321     SkBitmap bitmap;
   1322     bitmap.installPixels(SkImageInfo::MakeN32Premul(image->width(), image->height()),
   1323                              &srcPixels.front(), rowBytes);
   1324     canvas->drawBitmap(bitmap, 0, 0);
   1325 ##
   1326 
   1327 #SeeAlso scalePixels SkBitmap::readPixels SkPixmap::readPixels SkCanvas::readPixels SkSurface::readPixels
   1328 
   1329 #Method ##
   1330 
   1331 # ------------------------------------------------------------------------------
   1332 
   1333 #Method bool scalePixels(const SkPixmap& dst, SkFilterQuality filterQuality,
   1334                      CachingHint cachingHint = kAllow_CachingHint) const
   1335 #In Pixels
   1336 #Line # scales and converts one Image to another ##
   1337 #Populate
   1338 
   1339 #Example
   1340 #Image 3
   1341 #Height 128
   1342     std::vector<int32_t> srcPixels;
   1343     int quarterWidth = image->width() / 16;
   1344     int rowBytes = quarterWidth * 4;
   1345     int quarterHeight = image->height() / 16;
   1346     srcPixels.resize(quarterHeight * rowBytes);
   1347     SkPixmap pixmap(SkImageInfo::MakeN32Premul(quarterWidth, quarterHeight),
   1348                     &srcPixels.front(), rowBytes);
   1349     canvas->scale(4, 4);
   1350     SkFilterQuality qualities[] = { kNone_SkFilterQuality, kLow_SkFilterQuality,
   1351                      kMedium_SkFilterQuality, kHigh_SkFilterQuality };
   1352     for (unsigned index = 0; index < SK_ARRAY_COUNT(qualities); ++index) {
   1353         image->scalePixels(pixmap, qualities[index]);
   1354         sk_sp<SkImage> filtered = SkImage::MakeFromRaster(pixmap, nullptr, nullptr);
   1355         canvas->drawImage(filtered, 16 * index, 0);
   1356     }
   1357 ##
   1358 
   1359 #SeeAlso SkCanvas::drawImage readPixels SkPixmap::scalePixels
   1360 
   1361 #Method ##
   1362 
   1363 # ------------------------------------------------------------------------------
   1364 
   1365 #Method sk_sp<SkData> encodeToData(SkEncodedImageFormat encodedImageFormat, int quality) const
   1366 #In Utility
   1367 #Line # returns encoded Image as SkData ##
   1368 #Populate
   1369 
   1370 #Example
   1371 #Image 3
   1372     canvas->scale(4, 4);
   1373     SkIRect subset = {0, 0, 16, 64};
   1374     int x = 0;
   1375     for (int quality : { 0, 10, 50, 100 } ) {
   1376         sk_sp<SkData> data(image->encodeToData(SkEncodedImageFormat::kJPEG, quality));
   1377         sk_sp<SkImage> filtered = SkImage::MakeFromEncoded(data, &subset);
   1378         canvas->drawImage(filtered, x, 0);
   1379         x += 16;
   1380     }
   1381 ##
   1382 
   1383 #SeeAlso refEncodedData MakeFromEncoded
   1384 
   1385 #Method ##
   1386 
   1387 # ------------------------------------------------------------------------------
   1388 
   1389 #Method sk_sp<SkData> encodeToData() const
   1390 #Populate
   1391 
   1392 #Example
   1393 #Image 3
   1394     canvas->scale(4, 4);
   1395     SkIRect subset = {136, 32, 200, 96};
   1396     sk_sp<SkData> data(image->encodeToData());
   1397     sk_sp<SkImage> eye = SkImage::MakeFromEncoded(data, &subset);
   1398     canvas->drawImage(eye, 0, 0);
   1399 ##
   1400 
   1401 #SeeAlso refEncodedData MakeFromEncoded
   1402 
   1403 #Method ##
   1404 
   1405 # ------------------------------------------------------------------------------
   1406 
   1407 #Method sk_sp<SkData> refEncodedData() const
   1408 #In Utility
   1409 #Line # returns Image encoded in SkData if present ##
   1410 #Populate
   1411 
   1412 #Example
   1413 #Image 3
   1414 #Platform gpu
   1415     struct {
   1416         const char* name;
   1417         sk_sp<SkImage> image;
   1418     } tests[] = { { "image", image }, { "bitmap", SkImage::MakeFromBitmap(source) },
   1419           { "texture", SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
   1420                             kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
   1421                             kOpaque_SkAlphaType, nullptr) } };
   1422     SkString string;
   1423     SkPaint paint;
   1424     for (const auto& test : tests ) {
   1425         if (!test.image) {
   1426             string.printf("no %s", test.name);
   1427         } else {
   1428             string.printf("%s" "encoded %s", test.image->refEncodedData() ? "" : "no ", test.name);
   1429         }
   1430         canvas->drawString(string, 10, 20, paint);
   1431         canvas->translate(0, 20);
   1432     }
   1433 ##
   1434 
   1435 #SeeAlso encodeToData MakeFromEncoded
   1436 
   1437 #Method ##
   1438 
   1439 # ------------------------------------------------------------------------------
   1440 #Subtopic Utility
   1441 #Line # rarely called management functions ##
   1442 ##
   1443 
   1444 #Method sk_sp<SkImage> makeSubset(const SkIRect& subset) const
   1445 #In Constructors
   1446 #Line # creates Image containing part of original ##
   1447 #Populate
   1448 
   1449 #Example
   1450 #Image 3
   1451     canvas->scale(.5f, .5f);
   1452     const int width = 64;
   1453     const int height = 64;
   1454     for (int y = 0; y < 512; y += height ) {
   1455         for (int x = 0; x < 512; x += width ) {
   1456             sk_sp<SkImage> subset(image->makeSubset({x, y, x + width, y + height}));
   1457             canvas->drawImage(subset, x * 3 / 2, y * 3 / 2);
   1458         }
   1459     }
   1460 ##
   1461 
   1462 #SeeAlso MakeFromEncoded
   1463 
   1464 #Method ##
   1465 
   1466 # ------------------------------------------------------------------------------
   1467 
   1468 #Method sk_sp<SkImage> makeTextureImage(GrContext* context, SkColorSpace* dstColorSpace,
   1469                                         GrMipMapped mipMapped = GrMipMapped::kNo) const
   1470 #In Constructors
   1471 #Line # creates Image matching Color_Space if possible ##
   1472 #Populate
   1473 
   1474 #Example
   1475 #Platform gpu
   1476 #Image 5
   1477     auto drawImage = [=](sk_sp<SkImage> image, GrContext* context, const char* label) -> void {
   1478         if (nullptr == image || nullptr == context) {
   1479             return;
   1480         }
   1481         SkPaint paint;
   1482         paint.setAntiAlias(true);
   1483         sk_sp<SkImage> texture(image->makeTextureImage(context, nullptr));
   1484         canvas->drawImage(texture, 0, 0);
   1485         canvas->drawString(label, 20, texture->height() / 4, paint);
   1486     };
   1487     sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
   1488     GrContext* context = canvas->getGrContext();
   1489     sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(context, backEndTexture,
   1490                                 kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
   1491                                 kOpaque_SkAlphaType, nullptr));
   1492     drawImage(image, context, "image");
   1493     canvas->translate(image->width(), 0);
   1494     drawImage(bitmapImage, context, "source");
   1495     canvas->translate(-image->width(), image->height());
   1496     drawImage(textureImage, context, "backEndTexture");
   1497 ##
   1498 
   1499 #SeeAlso MakeFromTexture
   1500 
   1501 #Method ##
   1502 
   1503 # ------------------------------------------------------------------------------
   1504 
   1505 #Method sk_sp<SkImage> makeNonTextureImage() const
   1506 #In Constructors
   1507 #Line # creates Image without dependency on GPU_Texture ##
   1508 #Populate
   1509 
   1510 #Example
   1511 #Image 5
   1512 #Platform gpu
   1513     auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {
   1514         if (nullptr == image) {
   1515             return;
   1516         }
   1517         SkPaint paint;
   1518         paint.setAntiAlias(true);
   1519         sk_sp<SkImage> nonTexture(image->makeNonTextureImage());
   1520         canvas->drawImage(nonTexture, 0, 0);
   1521         canvas->drawString(label, 20, nonTexture->height() / 4, paint);
   1522     };
   1523     sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
   1524     sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
   1525                                 kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
   1526                                 kOpaque_SkAlphaType, nullptr));
   1527     drawImage(image, "image");
   1528     canvas->translate(image->width(), 0);
   1529     drawImage(bitmapImage, "source");
   1530     canvas->translate(-image->width(), image->height());
   1531     drawImage(textureImage, "backEndTexture");
   1532 ##
   1533 
   1534 #SeeAlso makeTextureImage makeRasterImage MakeBackendTextureFromSkImage
   1535 
   1536 #Method ##
   1537 
   1538 # ------------------------------------------------------------------------------
   1539 
   1540 #Method sk_sp<SkImage> makeRasterImage() const
   1541 #In Constructors
   1542 #Line # creates Image compatible with Raster_Surface if possible ##
   1543 #Populate
   1544 
   1545 #Example
   1546 #Image 5
   1547 #Platform gpu
   1548     auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {
   1549         if (nullptr == image) {
   1550             return;
   1551         }
   1552         SkPaint paint;
   1553         paint.setAntiAlias(true);
   1554         sk_sp<SkImage> raster(image->makeRasterImage());
   1555         canvas->drawImage(raster, 0, 0);
   1556         canvas->drawString(label, 20, raster->height() / 4, paint);
   1557     };
   1558     sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
   1559     sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
   1560                                 kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
   1561                                 kOpaque_SkAlphaType, nullptr));
   1562     drawImage(image, "image");
   1563     canvas->translate(image->width(), 0);
   1564     drawImage(bitmapImage, "source");
   1565     canvas->translate(-image->width(), image->height());
   1566     drawImage(textureImage, "backEndTexture");
   1567 ##
   1568 
   1569 #SeeAlso isTextureBacked isLazyGenerated MakeFromRaster
   1570 
   1571 #Method ##
   1572 
   1573 # ------------------------------------------------------------------------------
   1574 
   1575 #Method sk_sp<SkImage> makeWithFilter(GrContext* context,
   1576                                   const SkImageFilter* filter, const SkIRect& subset,
   1577                                   const SkIRect& clipBounds, SkIRect* outSubset,
   1578                                   SkIPoint* offset) const
   1579 #In Constructors
   1580 #Line # creates filtered, clipped Image ##
   1581 #Populate
   1582 
   1583 #Example
   1584 #Description
   1585 In each frame of the animation, filtered Image is drawn in a different location.
   1586 By translating canvas by returned offset, Image appears stationary.
   1587 ##
   1588 #Image 5
   1589 #Platform gpu
   1590 #Duration 1
   1591     sk_sp<SkImageFilter> shadowFilter = SkDropShadowImageFilter::Make(
   1592                 -10.0f * frame, 5.0f * frame, 3.0f, 3.0f, SK_ColorBLUE,
   1593                 SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
   1594                 nullptr);
   1595     sk_sp<SkImageFilter> offsetFilter = SkOffsetImageFilter::Make(40, 40, shadowFilter, nullptr);
   1596     SkIRect subset = image->bounds();
   1597     SkIRect clipBounds = image->bounds();
   1598     clipBounds.outset(60, 60);
   1599     SkIRect outSubset;
   1600     SkIPoint offset;
   1601     sk_sp<SkImage> filtered(image->makeWithFilter(canvas->getGrContext(),
   1602                             offsetFilter.get(), subset, clipBounds,
   1603                             &outSubset, &offset));
   1604     SkPaint paint;
   1605     paint.setAntiAlias(true);
   1606     paint.setStyle(SkPaint::kStroke_Style);
   1607     canvas->drawLine(0, 0, offset.fX, offset.fY, paint);
   1608     canvas->translate(offset.fX, offset.fY);
   1609     canvas->drawImage(filtered, 0, 0);
   1610     canvas->drawRect(SkRect::Make(outSubset), paint);
   1611 ##
   1612 
   1613 #SeeAlso makeShader SkPaint::setImageFilter
   1614 
   1615 #Method ##
   1616 
   1617 # ------------------------------------------------------------------------------
   1618 
   1619 #Method sk_sp<SkImage> makeWithFilter(const SkImageFilter* filter, const SkIRect& subset,
   1620                                   const SkIRect& clipBounds, SkIRect* outSubset,
   1621                                   SkIPoint* offset) const
   1622 #In  Constructors
   1623 #Line # creates filtered, clipped Image ##
   1624 #Populate
   1625 #NoExample
   1626 ##
   1627 #SeeAlso makeShader SkPaint::setImageFilter
   1628 #Method ##
   1629 
   1630 # ------------------------------------------------------------------------------
   1631 
   1632 #Typedef std::function<void(GrBackendTexture)> BackendTextureReleaseProc
   1633 #Line # parameter type for MakeBackendTextureFromSkImage ##
   1634 
   1635 #Code
   1636 #Populate
   1637 ##
   1638 
   1639 Defines a callback function, taking one parameter of type GrBackendTexture with
   1640 no return value. Function is called when back-end texture is to be released.
   1641 ##
   1642 
   1643 # ------------------------------------------------------------------------------
   1644 
   1645 #Method static bool MakeBackendTextureFromSkImage(GrContext* context,
   1646                                               sk_sp<SkImage> image,
   1647                                               GrBackendTexture* backendTexture,
   1648                                               BackendTextureReleaseProc* backendTextureReleaseProc)
   1649 #In Constructors
   1650 #Line # creates GPU_Texture from Image ##
   1651 #Populate
   1652 
   1653 #Example
   1654 #Platform gpu
   1655 #Height 64
   1656 #Function
   1657 static sk_sp<SkImage> create_gpu_image(GrContext* grContext) {
   1658     const SkImageInfo info = SkImageInfo::MakeN32(20, 20, kOpaque_SkAlphaType);
   1659     auto surface(SkSurface::MakeRenderTarget(grContext, SkBudgeted::kNo, info));
   1660     SkCanvas* canvas = surface->getCanvas();
   1661     canvas->clear(SK_ColorWHITE);
   1662     SkPaint paint;
   1663     paint.setColor(SK_ColorBLACK);
   1664     canvas->drawRect(SkRect::MakeXYWH(5, 5, 10, 10), paint);
   1665     return surface->makeImageSnapshot();
   1666 }
   1667 ##
   1668 
   1669 void draw(SkCanvas* canvas) {
   1670     GrContext* grContext = canvas->getGrContext();
   1671     if (!grContext) {
   1672         return;
   1673     }
   1674     sk_sp<SkImage> backEndImage = create_gpu_image(grContext);
   1675     canvas->drawImage(backEndImage, 0, 0);
   1676     GrBackendTexture texture;
   1677     SkImage::BackendTextureReleaseProc proc;
   1678     if (!SkImage::MakeBackendTextureFromSkImage(grContext, std::move(backEndImage),
   1679             &texture, &proc)) {
   1680         return;
   1681     }
   1682     sk_sp<SkImage> i2 = SkImage::MakeFromTexture(grContext, texture, kTopLeft_GrSurfaceOrigin,
   1683             kN32_SkColorType, kOpaque_SkAlphaType, nullptr);
   1684     canvas->drawImage(i2, 30, 30);
   1685 }
   1686 ##
   1687 
   1688 #SeeAlso MakeFromTexture makeTextureImage
   1689 
   1690 #Method ##
   1691 
   1692 # ------------------------------------------------------------------------------
   1693 
   1694 #Method bool isLazyGenerated() const
   1695 #In Property
   1696 #Line # returns if Image is created as needed ##
   1697 #Populate
   1698 
   1699 #Example
   1700 #Height 80
   1701 #Function
   1702 class TestImageGenerator : public SkImageGenerator {
   1703 public:
   1704     TestImageGenerator() : SkImageGenerator(SkImageInfo::MakeN32Premul(10, 10)) {}
   1705     ~TestImageGenerator() override {}
   1706 protected:
   1707     bool onGetPixels(const SkImageInfo& info, void* pixelPtr, size_t rowBytes,
   1708                      const Options& options) override {
   1709         SkPMColor* pixels = static_cast<SkPMColor*>(pixelPtr);
   1710         for (int y = 0; y < info.height(); ++y) {
   1711             for (int x = 0; x < info.width(); ++x) {
   1712                 pixels[y * info.width() + x] = 0xff223344 + y * 0x000C0811;
   1713             }
   1714         }
   1715         return true;
   1716     }
   1717 };
   1718 ##
   1719 void draw(SkCanvas* canvas) {
   1720     auto gen = std::unique_ptr<TestImageGenerator>(new TestImageGenerator());
   1721     sk_sp<SkImage> image(SkImage::MakeFromGenerator(std::move(gen)));
   1722     SkString lazy(image->isLazyGenerated() ? "is lazy" : "not lazy");
   1723     canvas->scale(8, 8);
   1724     canvas->drawImage(image, 0, 0, nullptr);
   1725     SkPaint paint;
   1726     paint.setTextSize(4);
   1727     canvas->drawString(lazy, 2, 5, paint);
   1728 }
   1729 ##
   1730 
   1731 #Example
   1732 #Image 5
   1733 #Platform gpu
   1734 void draw(SkCanvas* canvas) {
   1735     auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {
   1736         if (nullptr == image) {
   1737             return;
   1738         }
   1739         SkPaint paint;
   1740         paint.setAntiAlias(true);
   1741         canvas->drawImage(image, 0, 0);
   1742         canvas->drawString(label, 30, image->height() / 4, paint);
   1743         canvas->drawString(
   1744                 image->isLazyGenerated() ? "is lazily generated" : "not lazily generated",
   1745                 20, image->height() * 3 / 4, paint);
   1746     };
   1747     sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
   1748     sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
   1749                                 kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
   1750                                 kOpaque_SkAlphaType, nullptr));
   1751     drawImage(image, "image");
   1752     canvas->translate(image->width(), 0);
   1753     drawImage(bitmapImage, "source");
   1754     canvas->translate(-image->width(), image->height());
   1755     drawImage(textureImage, "backEndTexture");
   1756 }
   1757 ##
   1758 
   1759 #SeeAlso isTextureBacked makeNonTextureImage
   1760 
   1761 #Method ##
   1762 
   1763 # ------------------------------------------------------------------------------
   1764 
   1765 #Method sk_sp<SkImage> makeColorSpace(sk_sp<SkColorSpace> target) const
   1766 #In Constructors
   1767 #Line # creates Image matching Color_Space if possible ##
   1768 #Populate
   1769 
   1770 #Example
   1771 #Image 5
   1772 #Set sRGB
   1773     sk_sp<SkColorSpace> normalColorSpace = SkColorSpace::MakeRGB(
   1774              SkNamedTransferFn::kSRGB, SkNamedGamut::kSRGB);
   1775     sk_sp<SkColorSpace> wackyColorSpace = normalColorSpace->makeColorSpin();
   1776     for (auto colorSpace : { normalColorSpace, wackyColorSpace  } ) {
   1777         sk_sp<SkImage> colorSpaced = image->makeColorSpace(colorSpace);
   1778         canvas->drawImage(colorSpaced, 0, 0);
   1779         canvas->translate(128, 0);
   1780     }
   1781 ##
   1782 
   1783 #SeeAlso MakeFromPicture MakeFromTexture
   1784 
   1785 #Method ##
   1786 
   1787 #Class SkImage ##
   1788 
   1789 #Topic Image ##
   1790