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