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