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#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
277User 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
296A back-end texture has been created and uploaded to the GPU outside of this example.
297##
298GrContext* context = canvas->getGrContext();
299if (!context) {
300   return;
301}
302canvas->scale(.25f, .25f);
303int x = 0;
304for (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);
308x += 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
330textureReleaseProc may be called at some later point in time. In this example,
331textureReleaseProc has no effect on the drawing.
332##
333#Platform gpu
334#Image 4
335GrContext* context = canvas->getGrContext();
336if (!context) {
337   return;
338}
339auto debugster = [](SkImage::ReleaseContext releaseContext) -> void {
340   *((int *) releaseContext) += 128;
341};
342int x = 0, y = 0;
343for (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
368GrContext* context = canvas->getGrContext();
369sk_sp<SkData> encodedData = image->encodeToData(SkEncodedImageFormat::kJPEG, 100);
370sk_sp<SkImage> image = SkImage::MakeCrossContextFromEncoded(context,
371                                                            encodedData, false, nullptr);
372canvas->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
392GrContext* context = canvas->getGrContext();
393SkPixmap pixmap;
394if (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 ##
607Use 8 bits per ARGB component using unsigned integer format.
608##
609#Const kF16 1
610#Line # uses 16-bit float per Color component ##
611Use 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
736dimensionsAsBounds == 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 ##
796Returns Alpha_Type, one of: #list_of_alpha_types#.
797
798Alpha_Type returned was a parameter to an Image constructor,
799or 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
915alphaOnly = 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
940isOpaque = false
941isOpaque = 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
959SkMatrix matrix;
960matrix.setRotate(45);
961SkPaint paint;
962paint.setShader(image->makeShader(SkShader::kRepeat_TileMode, SkShader::kMirror_TileMode,
963                                  &matrix));
964canvas->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
978SkMatrix matrix;
979matrix.setRotate(45);
980matrix.postTranslate(125, 30);
981SkPaint paint;
982paint.setShader(image->makeShader(&matrix));
983canvas->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
1048auto 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};
1059sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
1060sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
1061                            kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
1062                            kOpaque_SkAlphaType, nullptr));
1063drawImage(image, "image");
1064canvas->translate(image->width(), 0);
1065drawImage(bitmapImage, "source");
1066canvas->translate(-image->width(), image->height());
1067drawImage(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
1084auto 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};
1099sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
1100sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
1101                            kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
1102                            kOpaque_SkAlphaType, nullptr));
1103drawImage(image, "image");
1104canvas->translate(image->width(), 0);
1105drawImage(bitmapImage, "source");
1106canvas->translate(-image->width(), image->height());
1107drawImage(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
1154CachingHint selects whether Skia may internally cache Bitmaps generated by
1155decoding Image, or by copying Image from GPU to CPU. The default behavior
1156allows caching Bitmaps.
1157
1158Choose kDisallow_CachingHint if Image pixels are to be used only once, or
1159if Image pixels reside in a cache outside of Skia, or to reduce memory pressure.
1160
1161Choosing kAllow_CachingHint does not ensure that pixels will be cached.
1162Image pixels may not be cached if memory requirements are too large or
1163pixels 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
1186Copies Rect of pixels from Image to dstPixels. Copy starts at offset (srcX, srcY),
1187and does not exceed Image (width(), height()).
1188
1189dstInfo specifies width, height, Color_Type, Alpha_Type, and Color_Space of
1190destination. dstRowBytes specifics the gap from one destination row to the next.
1191Returns 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
1198Pixels are copied only if pixel conversion is possible. If Image Color_Type is
1199kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType() must match.
1200If Image Color_Type is kGray_8_SkColorType, dstInfo.colorSpace() must match.
1201If Image Alpha_Type is kOpaque_SkAlphaType, dstInfo.alphaType() must
1202match. If Image Color_Space is nullptr, dstInfo.colorSpace() must match. Returns
1203false if pixel conversion is not possible.
1204
1205srcX and srcY may be negative to copy only top or left of source. Returns
1206false if width() or height() is zero or negative.
1207Returns false if #Formula # abs(srcX) >= Image width() ##, or if #Formula # abs(srcY) >= Image height() ##.
1208
1209If cachingHint is kAllow_CachingHint, pixels may be retained locally.
1210If 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
1252Copies a Rect of pixels from Image to dst. Copy starts at (srcX, srcY), and
1253does not exceed Image (width(), height()).
1254
1255dst specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
1256and row bytes of destination. dst.rowBytes() specifics the gap from one destination
1257row 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
1264Pixels are copied only if pixel conversion is possible. If Image Color_Type is
1265kGray_8_SkColorType, or kAlpha_8_SkColorType; dst.colorType() must match.
1266If Image Color_Type is kGray_8_SkColorType, dst.colorSpace() must match.
1267If Image Alpha_Type is kOpaque_SkAlphaType, dst.alphaType() must
1268match. If Image Color_Space is nullptr, dst.colorSpace() must match. Returns
1269false if pixel conversion is not possible.
1270
1271srcX and srcY may be negative to copy only top or left of source. Returns
1272false if width() or height() is zero or negative.
1273Returns false if #Formula # abs(srcX) >= Image width() ##, or if #Formula # abs(srcY) >= Image height() ##.
1274
1275If cachingHint is kAllow_CachingHint, pixels may be retained locally.
1276If 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
1565In each frame of the animation, filtered Image is drawn in a different location.
1566By 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
1619Defines a callback function, taking one parameter of type GrBackendTexture with
1620no 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
1637static 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
1649void 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
1682class TestImageGenerator : public SkImageGenerator {
1683public:
1684    TestImageGenerator() : SkImageGenerator(SkImageInfo::MakeN32Premul(10, 10)) {}
1685    ~TestImageGenerator() override {}
1686protected:
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##
1699void 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
1714void 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