1#Topic Image
2#Alias Image_Reference ##
3
4#Class SkImage
5
6#Code
7#Populate
8##
9
10Image describes a two dimensional array of pixels to draw. The pixels may be
11decoded in a Raster_Bitmap, encoded in a Picture or compressed data stream,
12or located in GPU memory as a GPU_Texture.
13
14Image cannot be modified after it is created. Image may allocate additional
15storage as needed; for instance, an encoded Image may decode when drawn.
16
17Image width and height are greater than zero. Creating an Image with zero width
18or height returns Image equal to nullptr.
19
20Image may be created from Bitmap, Pixmap, Surface, Picture, encoded streams,
21GPU_Texture, YUV_ColorSpace data, or hardware buffer. Encoded streams supported
22include BMP, GIF, HEIF, ICO, JPEG, PNG, WBMP, WebP. Supported encoding details
23vary with platform.
24
25#Subtopic Raster_Image
26#Alias Raster_Image ##
27#Line # pixels decoded in Raster_Bitmap ##
28Raster_Image pixels are decoded in a Raster_Bitmap. These pixels may be read
29directly and in most cases written to, although edited pixels may not be drawn
30if Image has been copied internally.
31##
32
33#Subtopic Texture_Image
34#Line # pixels located on GPU ##
35Texture_Image are located on GPU and pixels are not accessible. Texture_Image
36are allocated optimally for best performance. Raster_Image may
37be drawn to GPU_Surface, but pixels are uploaded from CPU to GPU downgrading
38performance.
39##
40
41#Subtopic Lazy_Image
42#Line # deferred pixel buffer ##
43Lazy_Image defer allocating buffer for Image pixels and decoding stream until
44Image is drawn. Lazy_Image caches result if possible to speed up repeated
45drawing.
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
58Draw a five by five bitmap, and draw a copy in an Image. Editing the pixmap
59alters the bitmap draw, but does not alter the Image draw since the Image
60contains 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
115Caller 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
128Function called when Image no longer shares pixels. ReleaseContext is
129provided 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
144static void releaseProc(const void* pixels, SkImage::ReleaseContext context) {
145     int* countPtr = static_cast<int*>(context);
146     *countPtr += 1;
147}
148##
149
150void 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
160before reset: 0
161after 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
178The first Bitmap is shared; writing to the pixel memory changes the first
179Image.
180The second Bitmap is marked immutable, and is copied; writing to the pixel
181memory 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
217The 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
241int x = 0;
242for (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
262Used to inform MakeFromCompressed which compression method was used on the
263input 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
297User 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
316A back-end texture has been created and uploaded to the GPU outside of this example.
317##
318GrContext* context = canvas->getGrContext();
319if (!context) {
320   return;
321}
322canvas->scale(.25f, .25f);
323int x = 0;
324for (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);
328x += 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
350textureReleaseProc may be called at some later point in time. In this example,
351textureReleaseProc has no effect on the drawing.
352##
353#Platform gpu
354#Image 4
355GrContext* context = canvas->getGrContext();
356if (!context) {
357   return;
358}
359auto debugster = [](SkImage::ReleaseContext releaseContext) -> void {
360   *((int *) releaseContext) += 128;
361};
362int x = 0, y = 0;
363for (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
388GrContext* context = canvas->getGrContext();
389sk_sp<SkData> encodedData = image->encodeToData(SkEncodedImageFormat::kJPEG, 100);
390sk_sp<SkImage> image = SkImage::MakeCrossContextFromEncoded(context,
391                                                            encodedData, false, nullptr);
392canvas->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
412GrContext* context = canvas->getGrContext();
413SkPixmap pixmap;
414if (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 ##
627Use 8 bits per ARGB component using unsigned integer format.
628##
629#Const kF16 1
630#Line # uses 16-bit float per Color component ##
631Use 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
756dimensionsAsBounds == 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 ##
816Returns Alpha_Type, one of: #list_of_alpha_types#.
817
818Alpha_Type returned was a parameter to an Image constructor,
819or 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
935alphaOnly = 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
960isOpaque = false
961isOpaque = 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
979SkMatrix matrix;
980matrix.setRotate(45);
981SkPaint paint;
982paint.setShader(image->makeShader(SkShader::kRepeat_TileMode, SkShader::kMirror_TileMode,
983                                  &matrix));
984canvas->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
998SkMatrix matrix;
999matrix.setRotate(45);
1000matrix.postTranslate(125, 30);
1001SkPaint paint;
1002paint.setShader(image->makeShader(&matrix));
1003canvas->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
1068auto 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};
1079sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
1080sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
1081                            kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
1082                            kOpaque_SkAlphaType, nullptr));
1083drawImage(image, "image");
1084canvas->translate(image->width(), 0);
1085drawImage(bitmapImage, "source");
1086canvas->translate(-image->width(), image->height());
1087drawImage(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
1104auto 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};
1119sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
1120sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
1121                            kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
1122                            kOpaque_SkAlphaType, nullptr));
1123drawImage(image, "image");
1124canvas->translate(image->width(), 0);
1125drawImage(bitmapImage, "source");
1126canvas->translate(-image->width(), image->height());
1127drawImage(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
1174CachingHint selects whether Skia may internally cache Bitmaps generated by
1175decoding Image, or by copying Image from GPU to CPU. The default behavior
1176allows caching Bitmaps.
1177
1178Choose kDisallow_CachingHint if Image pixels are to be used only once, or
1179if Image pixels reside in a cache outside of Skia, or to reduce memory pressure.
1180
1181Choosing kAllow_CachingHint does not ensure that pixels will be cached.
1182Image pixels may not be cached if memory requirements are too large or
1183pixels 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
1206Copies Rect of pixels from Image to dstPixels. Copy starts at offset (srcX, srcY),
1207and does not exceed Image (width(), height()).
1208
1209dstInfo specifies width, height, Color_Type, Alpha_Type, and Color_Space of
1210destination. dstRowBytes specifics the gap from one destination row to the next.
1211Returns 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
1218Pixels are copied only if pixel conversion is possible. If Image Color_Type is
1219kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType() must match.
1220If Image Color_Type is kGray_8_SkColorType, dstInfo.colorSpace() must match.
1221If Image Alpha_Type is kOpaque_SkAlphaType, dstInfo.alphaType() must
1222match. If Image Color_Space is nullptr, dstInfo.colorSpace() must match. Returns
1223false if pixel conversion is not possible.
1224
1225srcX and srcY may be negative to copy only top or left of source. Returns
1226false if width() or height() is zero or negative.
1227Returns false if #Formula # abs(srcX) >= Image width() ##, or if #Formula # abs(srcY) >= Image height() ##.
1228
1229If cachingHint is kAllow_CachingHint, pixels may be retained locally.
1230If 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
1272Copies a Rect of pixels from Image to dst. Copy starts at (srcX, srcY), and
1273does not exceed Image (width(), height()).
1274
1275dst specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
1276and row bytes of destination. dst.rowBytes() specifics the gap from one destination
1277row 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
1284Pixels are copied only if pixel conversion is possible. If Image Color_Type is
1285kGray_8_SkColorType, or kAlpha_8_SkColorType; dst.colorType() must match.
1286If Image Color_Type is kGray_8_SkColorType, dst.colorSpace() must match.
1287If Image Alpha_Type is kOpaque_SkAlphaType, dst.alphaType() must
1288match. If Image Color_Space is nullptr, dst.colorSpace() must match. Returns
1289false if pixel conversion is not possible.
1290
1291srcX and srcY may be negative to copy only top or left of source. Returns
1292false if width() or height() is zero or negative.
1293Returns false if #Formula # abs(srcX) >= Image width() ##, or if #Formula # abs(srcY) >= Image height() ##.
1294
1295If cachingHint is kAllow_CachingHint, pixels may be retained locally.
1296If 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
1585In each frame of the animation, filtered Image is drawn in a different location.
1586By 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
1639Defines a callback function, taking one parameter of type GrBackendTexture with
1640no 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
1657static 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
1669void 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
1702class TestImageGenerator : public SkImageGenerator {
1703public:
1704    TestImageGenerator() : SkImageGenerator(SkImageInfo::MakeN32Premul(10, 10)) {}
1705    ~TestImageGenerator() override {}
1706protected:
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##
1719void 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
1734void 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