1#Topic Bitmap 2#Alias Bitmaps ## 3#Alias Bitmap_Reference ## 4 5#Class SkBitmap 6#Line # two-dimensional raster pixel array ## 7 8#Code 9#Populate 10## 11 12Bitmap describes a two-dimensional raster pixel array. Bitmap is built on 13Image_Info, containing integer width and height, Color_Type and Alpha_Type 14describing the pixel format, and Color_Space describing the range of colors. 15Bitmap points to Pixel_Ref, which describes the physical array of pixels. 16Image_Info bounds may be located anywhere fully inside Pixel_Ref bounds. 17 18Bitmap can be drawn using Canvas. Bitmap can be a drawing destination for Canvas 19draw member functions. Bitmap flexibility as a pixel container limits some 20optimizations available to the target platform. 21 22If pixel array is primarily read-only, use Image for better performance. 23If pixel array is primarily written to, use Surface for better performance. 24 25Declaring SkBitmap const prevents altering Image_Info: the Bitmap height, width, 26and so on cannot change. It does not affect Pixel_Ref: a caller may write its 27pixels. Declaring SkBitmap const affects Bitmap configuration, not its contents. 28 29Bitmap is not thread safe. Each thread must have its own copy of Bitmap fields, 30although threads may share the underlying pixel array. 31 32#Subtopic Row_Bytes 33#Line # interval from one row to the next ## 34Bitmap pixels may be contiguous, or may have a gap at the end of each row. 35Row_Bytes is the interval from one row to the next. Row_Bytes may be specified; 36sometimes passing zero will compute the Row_Bytes from the row width and the 37number of bytes in a pixel. Row_Bytes may be larger than the row requires. This 38is useful to position one or more Bitmaps within a shared pixel array. 39## 40 41# ------------------------------------------------------------------------------ 42 43#Class Allocator 44#Line # abstract subclass of HeapAllocator ## 45#Code 46#Populate 47## 48 49Abstract subclass of HeapAllocator. 50 51# ------------------------------------------------------------------------------ 52 53#Method virtual bool allocPixelRef(SkBitmap* bitmap) = 0 54#Line # allocates pixel memory ## 55#Populate 56 57#NoExample 58## 59 60#SeeAlso HeapAllocator 61 62## 63 64#Class Allocator ## 65 66# ------------------------------------------------------------------------------ 67 68#Class HeapAllocator 69#Line # allocates pixel memory from heap ## 70 71#Code 72#Populate 73## 74 75Subclass of SkBitmap::Allocator that returns a Pixel_Ref that allocates its pixel 76memory from the heap. This is the default SkBitmap::Allocator invoked by 77allocPixels. 78 79# ------------------------------------------------------------------------------ 80 81#Method bool allocPixelRef(SkBitmap* bitmap) override 82#Line # allocates pixel memory ## 83#Populate 84 85#Example 86 SkBitmap bitmap; 87 bitmap.setInfo(SkImageInfo::MakeN32(16, 16, kPremul_SkAlphaType)); 88 SkDebugf("pixel address = %p\n", bitmap.getPixels()); 89 SkBitmap::HeapAllocator stdalloc; 90 if (!stdalloc.allocPixelRef(&bitmap)) { 91 SkDebugf("pixel allocation failed\n"); 92 } else { 93 SkDebugf("pixel address = %p\n", bitmap.getPixels()); 94 } 95#StdOut 96#Volatile 97pixel address = (nil) 98pixel address = 0x560ddd0ac670 99## 100## 101 102#SeeAlso SkBitmap::Allocator tryAllocPixels 103 104## 105 106#Class HeapAllocator ## 107 108# ------------------------------------------------------------------------------ 109 110#Method SkBitmap() 111 112#Line # constructs with default values ## 113#Populate 114 115#Example 116void draw(SkCanvas* canvas) { 117 const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"}; 118 const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x", 119 "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"}; 120 SkBitmap bitmap; 121 for (int i = 0; i < 2; ++i) { 122 SkDebugf("width: %2d height: %2d", bitmap.width(), bitmap.height()); 123 SkDebugf(" color: k%s_SkColorType", colors[bitmap.colorType()]); 124 SkDebugf(" alpha: k%s_SkAlphaType\n", alphas[bitmap.alphaType()]); 125 bitmap.setInfo(SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType), 126 0); 127 } 128} 129#StdOut 130width: 0 height: 0 color: kUnknown_SkColorType alpha: kUnknown_SkAlphaType 131width: 25 height: 35 color: kRGBA_8888_SkColorType alpha: kOpaque_SkAlphaType 132## 133## 134 135#SeeAlso setInfo 136 137## 138 139# ------------------------------------------------------------------------------ 140 141#Method SkBitmap(const SkBitmap& src) 142 143#Line # shares ownership of pixels ## 144#Populate 145 146#Example 147void draw(SkCanvas* canvas) { 148 SkBitmap original; 149 if (original.tryAllocPixels( 150 SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType))) { 151 SkDebugf("original has pixels before copy: %s\n", original.getPixels() ? "true" : "false"); 152 SkBitmap copy(original); 153 SkDebugf("original has pixels after copy: %s\n", original.getPixels() ? "true" : "false"); 154 SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false"); 155 } 156} 157#StdOut 158original has pixels before copy: true 159original has pixels after copy: true 160copy has pixels: true 161## 162## 163 164#SeeAlso setInfo setPixelRef setPixels swap 165 166## 167 168# ------------------------------------------------------------------------------ 169 170#Method SkBitmap(SkBitmap&& src) 171 172#Line # takes ownership of pixels ## 173#Populate 174 175#Example 176void draw(SkCanvas* canvas) { 177 SkBitmap original; 178 if (original.tryAllocPixels( 179 SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType))) { 180 SkDebugf("original has pixels before move: %s\n", original.getPixels() ? "true" : "false"); 181 SkBitmap copy(std::move(original)); 182 SkDebugf("original has pixels after move: %s\n", original.getPixels() ? "true" : "false"); 183 SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false"); 184 } 185} 186#StdOut 187original has pixels before move: true 188original has pixels after move: false 189copy has pixels: true 190## 191## 192 193#SeeAlso setInfo setPixelRef setPixels swap 194 195## 196 197# ------------------------------------------------------------------------------ 198 199#Method ~SkBitmap() 200 201#Line # releases ownership of pixels ## 202#Populate 203 204#NoExample 205## 206 207#SeeAlso Pixel_Ref 208 209## 210 211# ------------------------------------------------------------------------------ 212 213#Method SkBitmap& operator=(const SkBitmap& src) 214 215#Line # shares ownership of pixels ## 216#Populate 217 218#Example 219void draw(SkCanvas* canvas) { 220 SkBitmap original; 221 if (original.tryAllocPixels( 222 SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType))) { 223 SkDebugf("original has pixels before copy: %s\n", original.getPixels() ? "true" : "false"); 224 SkBitmap copy = original; 225 SkDebugf("original has pixels after copy: %s\n", original.getPixels() ? "true" : "false"); 226 SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false"); 227 } 228} 229#StdOut 230original has pixels before copy: true 231original has pixels after copy: true 232copy has pixels: true 233## 234## 235 236#SeeAlso setInfo setPixelRef setPixels swap 237 238## 239 240# ------------------------------------------------------------------------------ 241 242#Method SkBitmap& operator=(SkBitmap&& src) 243 244#Line # takes ownership of pixels ## 245#Populate 246 247#Example 248void draw(SkCanvas* canvas) { 249 SkBitmap original; 250 if (original.tryAllocPixels( 251 SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType))) { 252 SkDebugf("original has pixels before move: %s\n", original.getPixels() ? "true" : "false"); 253 SkBitmap copy = std::move(original); 254 SkDebugf("original has pixels after move: %s\n", original.getPixels() ? "true" : "false"); 255 SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false"); 256 } 257} 258#StdOut 259original has pixels before move: true 260original has pixels after move: false 261copy has pixels: true 262## 263## 264 265#SeeAlso setInfo setPixelRef setPixels swap 266 267## 268 269# ------------------------------------------------------------------------------ 270 271#Method void swap(SkBitmap& other) 272#In Utility 273#Line # exchanges Bitmap pair ## 274#Populate 275 276#Example 277void draw(SkCanvas* canvas) { 278 auto debugster = [](const char* prefix, const SkBitmap& b) -> void { 279 const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"}; 280 const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x", 281 "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"}; 282 SkDebugf("%s width:%d height:%d colorType:k%s_SkColorType alphaType:k%s_SkAlphaType\n", 283 prefix, b.width(), b.height(), colors[b.colorType()], alphas[b.alphaType()]); 284 }; 285 SkBitmap one, two; 286 if (!one.tryAllocPixels( 287 SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType))) { 288 return; 289 } 290 if (!two.tryAllocPixels( 291 SkImageInfo::Make(2, 2, kBGRA_8888_SkColorType, kPremul_SkAlphaType))) { 292 return; 293 } 294 for (int index = 0; index < 2; ++index) { 295 debugster("one", one); 296 debugster("two", two); 297 one.swap(two); 298 } 299} 300#StdOut 301one width:1 height:1 colorType:kRGBA_8888_SkColorType alphaType:kOpaque_SkAlphaType 302two width:2 height:2 colorType:kBGRA_8888_SkColorType alphaType:kPremul_SkAlphaType 303one width:2 height:2 colorType:kBGRA_8888_SkColorType alphaType:kPremul_SkAlphaType 304two width:1 height:1 colorType:kRGBA_8888_SkColorType alphaType:kOpaque_SkAlphaType 305## 306## 307 308#SeeAlso SkBitmap(SkBitmap&& src) operator=(SkBitmap&& src) 309 310## 311 312# ------------------------------------------------------------------------------ 313#Subtopic Property 314#Line # metrics and attributes ## 315## 316 317#Method const SkPixmap& pixmap() const 318#In Property 319#Line # returns Pixmap ## 320#Populate 321 322#Example 323 SkBitmap bitmap; 324 bitmap.allocPixels(SkImageInfo::MakeN32Premul(10, 11)); 325 SkCanvas offscreen(bitmap); 326 offscreen.clear(SK_ColorWHITE); 327 SkPaint paint; 328 offscreen.drawString("&", 0, 10, paint); 329 const SkPixmap& pixmap = bitmap.pixmap(); 330 if (pixmap.addr()) { 331 SkPMColor pmWhite = *pixmap.addr32(0, 0); 332 for (int y = 0; y < pixmap.height(); ++y) { 333 for (int x = 0; x < pixmap.width(); ++x) { 334 SkDebugf("%c", *pixmap.addr32(x, y) == pmWhite ? '-' : 'x'); 335 } 336 SkDebugf("\n"); 337 } 338 } 339 #StdOut 340---------- 341---xx----- 342--x--x---- 343--x------- 344--xx------ 345--x-x---x- 346-x---x--x- 347-x----xx-- 348-xx---x--- 349--xxxx-xx- 350---------- 351 #StdOut ## 352 353## 354 355#SeeAlso peekPixels installPixels readPixels writePixels 356 357## 358 359# ------------------------------------------------------------------------------ 360 361#Method const SkImageInfo& info() const 362#In Property 363#Line # returns Image_Info ## 364#Populate 365 366#Example 367#Image 4 368void draw(SkCanvas* canvas) { 369 // SkBitmap source; // pre-populated with soccer ball by fiddle.skia.org 370 const SkImageInfo& info = source.info(); 371 const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"}; 372 const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x", 373 "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"}; 374 SkDebugf("width: %d height: %d color: %s alpha: %s\n", info.width(), info.height(), 375 colors[info.colorType()], alphas[info.alphaType()]); 376#StdOut 377width: 56 height: 56 color: BGRA_8888 alpha: Opaque 378## 379} 380## 381 382#SeeAlso Image_Info 383 384## 385 386# ------------------------------------------------------------------------------ 387 388#Method int width() const 389#In Property 390#Line # returns pixel column count ## 391Returns pixel count in each row. Should be equal or less than 392#Formula # rowBytes() / info().bytesPerPixel() ##. 393 394May be less than pixelRef().width(). Will not exceed pixelRef().width() less 395pixelRefOrigin().fX. 396 397#Return pixel width in Image_Info ## 398 399#Example 400 SkImageInfo info = SkImageInfo::MakeA8(16, 32); 401 SkBitmap bitmap; 402 bitmap.setInfo(info); 403 SkDebugf("bitmap width: %d info width: %d\n", bitmap.width(), info.width()); 404#StdOut 405bitmap width: 16 info width: 16 406## 407## 408 409#SeeAlso height() SkPixelRef::width() SkImageInfo::width() 410 411## 412 413# ------------------------------------------------------------------------------ 414 415#Method int height() const 416#In Property 417#Line # returns pixel row count ## 418#Populate 419 420#Example 421 SkImageInfo info = SkImageInfo::MakeA8(16, 32); 422 SkBitmap bitmap; 423 bitmap.setInfo(info); 424 SkDebugf("bitmap height: %d info height: %d\n", bitmap.height(), info.height()); 425#StdOut 426bitmap height: 32 info height: 32 427## 428## 429 430#SeeAlso width() SkPixelRef::height() SkImageInfo::height() 431 432## 433 434# ------------------------------------------------------------------------------ 435 436#Method SkColorType colorType() const 437#In Property 438#Line # returns Image_Info Color_Type ## 439Returns Color_Type, one of: #list_of_color_types#. 440 441#Return Color_Type in Image_Info ## 442 443#Example 444 const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x", 445 "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"}; 446 SkBitmap bitmap; 447 bitmap.setInfo(SkImageInfo::MakeA8(16, 32)); 448 SkDebugf("color type: k" "%s" "_SkColorType\n", colors[bitmap.colorType()]); 449#StdOut 450color type: kAlpha_8_SkColorType 451## 452## 453 454#SeeAlso alphaType() SkImageInfo::colorType 455 456## 457 458# ------------------------------------------------------------------------------ 459 460#Method SkAlphaType alphaType() const 461#In Property 462#Line # returns Image_Info Alpha_Type ## 463Returns Alpha_Type, one of: #list_of_alpha_types#. 464 465#Return Alpha_Type in Image_Info ## 466 467#Example 468 const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"}; 469 SkPixmap pixmap(SkImageInfo::MakeA8(16, 32), nullptr, 64); 470 SkDebugf("alpha type: k" "%s" "_SkAlphaType\n", alphas[pixmap.alphaType()]); 471#StdOut 472alpha type: kPremul_SkAlphaType 473## 474## 475 476#SeeAlso colorType() SkImageInfo::alphaType 477 478## 479 480# ------------------------------------------------------------------------------ 481 482#Method SkColorSpace* colorSpace() const 483#In Property 484#Line # returns Image_Info Color_Space ## 485#Populate 486 487#Example 488#Description 489SkColorSpace::MakeSRGBLinear creates Color_Space with linear gamma 490and an sRGB gamut. This Color_Space gamma is not close to sRGB gamma. 491## 492 SkBitmap bitmap; 493 bitmap.setInfo(SkImageInfo::MakeN32(16, 32, kPremul_SkAlphaType, 494 SkColorSpace::MakeSRGBLinear())); 495 SkColorSpace* colorSpace = bitmap.colorSpace(); 496 SkDebugf("gammaCloseToSRGB: %s gammaIsLinear: %s isSRGB: %s\n", 497 colorSpace->gammaCloseToSRGB() ? "true" : "false", 498 colorSpace->gammaIsLinear() ? "true" : "false", 499 colorSpace->isSRGB() ? "true" : "false"); 500#StdOut 501gammaCloseToSRGB: false gammaIsLinear: true isSRGB: false 502## 503## 504 505#SeeAlso Color_Space SkImageInfo::colorSpace 506 507## 508 509# ------------------------------------------------------------------------------ 510 511#Method sk_sp<SkColorSpace> refColorSpace() const 512#In Property 513#Line # returns Image_Info Color_Space ## 514#Populate 515 516#Example 517 SkBitmap bitmap1, bitmap2; 518 bitmap1.setInfo(SkImageInfo::MakeN32(16, 32, kPremul_SkAlphaType, 519 SkColorSpace::MakeSRGBLinear())); 520 bitmap2.setInfo(SkImageInfo::MakeN32(16, 32, kPremul_SkAlphaType, 521 bitmap1.refColorSpace())); 522 SkColorSpace* colorSpace = bitmap2.colorSpace(); 523 SkDebugf("gammaCloseToSRGB: %s gammaIsLinear: %s isSRGB: %s\n", 524 colorSpace->gammaCloseToSRGB() ? "true" : "false", 525 colorSpace->gammaIsLinear() ? "true" : "false", 526 colorSpace->isSRGB() ? "true" : "false"); 527#StdOut 528gammaCloseToSRGB: false gammaIsLinear: true isSRGB: false 529## 530## 531 532#SeeAlso Color_Space SkImageInfo::colorSpace 533 534## 535 536# ------------------------------------------------------------------------------ 537 538#Method int bytesPerPixel() const 539#In Property 540#Line # returns number of bytes in pixel based on Color_Type ## 541#Populate 542 543#Example 544 const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x", 545 "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"}; 546 SkImageInfo info = SkImageInfo::MakeA8(1, 1); 547 SkBitmap bitmap; 548 for (SkColorType colorType : { #list_of_color_types# 549 } ) { 550 bitmap.setInfo(info.makeColorType(colorType)); 551 SkDebugf("color: k" "%s" "_SkColorType" "%*s" "bytesPerPixel: %d\n", 552 colors[colorType], 13 - strlen(colors[colorType]), " ", 553 bitmap.bytesPerPixel()); 554 } 555#StdOut 556color: kUnknown_SkColorType bytesPerPixel: 0 557color: kAlpha_8_SkColorType bytesPerPixel: 1 558color: kRGB_565_SkColorType bytesPerPixel: 2 559color: kARGB_4444_SkColorType bytesPerPixel: 2 560color: kRGBA_8888_SkColorType bytesPerPixel: 4 561color: kRGB_888x_SkColorType bytesPerPixel: 4 562color: kBGRA_8888_SkColorType bytesPerPixel: 4 563color: kRGBA_1010102_SkColorType bytesPerPixel: 4 564color: kRGB_101010x_SkColorType bytesPerPixel: 4 565color: kGray_8_SkColorType bytesPerPixel: 1 566color: kRGBA_F16_SkColorType bytesPerPixel: 8 567## 568## 569 570#SeeAlso rowBytes rowBytesAsPixels width shiftPerPixel SkImageInfo::bytesPerPixel 571 572## 573 574# ------------------------------------------------------------------------------ 575 576#Method int rowBytesAsPixels() const 577#In Property 578#Line # returns interval between rows in pixels ## 579#Populate 580 581#Example 582 SkBitmap bitmap; 583 for (int rowBytes : { 4, 5, 6, 7, 8} ) { 584 bitmap.setInfo(SkImageInfo::MakeN32(1, 1, kPremul_SkAlphaType), rowBytes); 585 SkDebugf("rowBytes: %d rowBytesAsPixels: %d\n", rowBytes, bitmap.rowBytesAsPixels()); 586 } 587#StdOut 588rowBytes: 4 rowBytesAsPixels: 1 589rowBytes: 5 rowBytesAsPixels: 1 590rowBytes: 6 rowBytesAsPixels: 1 591rowBytes: 7 rowBytesAsPixels: 1 592rowBytes: 8 rowBytesAsPixels: 2 593## 594## 595 596#SeeAlso rowBytes shiftPerPixel width bytesPerPixel 597 598## 599 600# ------------------------------------------------------------------------------ 601 602#Method int shiftPerPixel() const 603#In Property 604#Line # returns bit shift from pixels to bytes ## 605#Populate 606 607#Example 608 const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x", 609 "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"}; 610 SkImageInfo info = SkImageInfo::MakeA8(1, 1); 611 SkBitmap bitmap; 612 for (SkColorType colorType : { #list_of_color_types# 613 } ) { 614 bitmap.setInfo(info.makeColorType(colorType)); 615 SkDebugf("color: k" "%s" "_SkColorType" "%*s" "shiftPerPixel: %d\n", 616 colors[colorType], 14 - strlen(colors[colorType]), " ", 617 bitmap.shiftPerPixel()); 618 } 619#StdOut 620color: kUnknown_SkColorType shiftPerPixel: 0 621color: kAlpha_8_SkColorType shiftPerPixel: 0 622color: kRGB_565_SkColorType shiftPerPixel: 1 623color: kARGB_4444_SkColorType shiftPerPixel: 1 624color: kRGBA_8888_SkColorType shiftPerPixel: 2 625color: kRGB_888x_SkColorType shiftPerPixel: 2 626color: kBGRA_8888_SkColorType shiftPerPixel: 2 627color: kRGBA_1010102_SkColorType shiftPerPixel: 2 628color: kRGB_101010x_SkColorType shiftPerPixel: 2 629color: kGray_8_SkColorType shiftPerPixel: 0 630color: kRGBA_F16_SkColorType shiftPerPixel: 3 631## 632## 633 634#SeeAlso rowBytes rowBytesAsPixels width bytesPerPixel 635 636## 637 638# ------------------------------------------------------------------------------ 639 640#Method bool empty() const 641#In Property 642#Line # returns true if Image_Info has zero width() or height() ## 643#Populate 644 645#Example 646 SkBitmap bitmap; 647 for (int width : { 0, 2 } ) { 648 for (int height : { 0, 2 } ) { 649 bitmap.setInfo(SkImageInfo::MakeA8(width, height)); 650 SkDebugf("width: %d height: %d empty: %s\n", width, height, 651 bitmap.empty() ? "true" : "false"); 652 } 653 } 654#StdOut 655width: 0 height: 0 empty: true 656width: 0 height: 2 empty: true 657width: 2 height: 0 empty: true 658width: 2 height: 2 empty: false 659## 660## 661 662#SeeAlso height() width() drawsNothing 663 664## 665 666# ------------------------------------------------------------------------------ 667 668#Method bool isNull() const 669#In Property 670#Line # returns true if Pixel_Ref is nullptr ## 671#Populate 672 673#Example 674 SkBitmap bitmap; 675 SkDebugf("empty bitmap does %shave pixels\n", bitmap.isNull() ? "not " : ""); 676 bitmap.setInfo(SkImageInfo::MakeA8(8, 8)); 677 SkDebugf("bitmap with dimensions does %shave pixels\n", bitmap.isNull() ? "not " : ""); 678 bitmap.allocPixels(); 679 SkDebugf("allocated bitmap does %shave pixels\n", bitmap.isNull() ? "not " : ""); 680#StdOut 681empty bitmap does not have pixels 682bitmap with dimensions does not have pixels 683allocated bitmap does have pixels 684## 685## 686 687#SeeAlso empty() drawsNothing pixelRef 688 689## 690 691# ------------------------------------------------------------------------------ 692 693#Method bool drawsNothing() const 694#In Property 695#Line # returns true if no width(), no height(), or no Pixel_Ref ## 696#Populate 697 698#Example 699 SkBitmap bitmap; 700 for (int w : { 0, 8 } ) { 701 for (bool allocate : { false, true} ) { 702 bitmap.setInfo(SkImageInfo::MakeA8(w, 8)); 703 allocate ? bitmap.allocPixels() : (void) 0 ; 704 SkDebugf("empty:%s isNull:%s drawsNothing:%s\n", bitmap.empty() ? "true " : "false", 705 bitmap.isNull() ? "true " : "false", bitmap.drawsNothing() ? "true" : "false"); 706 } 707 } 708#StdOut 709empty:true isNull:true drawsNothing:true 710empty:true isNull:false drawsNothing:true 711empty:false isNull:true drawsNothing:true 712empty:false isNull:false drawsNothing:false 713## 714## 715 716#SeeAlso empty() isNull pixelRef 717 718## 719 720# ------------------------------------------------------------------------------ 721 722#Method size_t rowBytes() const 723#In Property 724#Line # returns interval between rows in bytes ## 725Returns row bytes, the interval from one pixel row to the next. Row bytes 726is at least as large as: #Formula # width() * info().bytesPerPixel() ##. 727 728Returns zero if colorType is kUnknown_SkColorType, or if row bytes supplied to 729setInfo is not large enough to hold a row of pixels. 730 731#Return byte length of pixel row ## 732 733#Example 734 SkBitmap bitmap; 735 for (int rowBytes : { 2, 8 } ) { 736 bool result = bitmap.setInfo(SkImageInfo::MakeA8(4, 4), rowBytes); 737 SkDebugf("setInfo returned:%s rowBytes:%d\n", result ? "true " : "false", bitmap.rowBytes()); 738 } 739#StdOut 740setInfo returned:false rowBytes:0 741setInfo returned:true rowBytes:8 742## 743## 744 745#SeeAlso info() setInfo SkImageInfo::minRowBytes 746 747## 748 749# ------------------------------------------------------------------------------ 750 751#Method bool setAlphaType(SkAlphaType alphaType) 752#In Set 753#Line # sets Alpha_Type of shared pixels ## 754#Populate 755 756#Example 757void draw(SkCanvas* canvas) { 758 const char* colors[] = { "Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x", 759 "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16" }; 760 const char* alphas[] = {"Unknown ", "Opaque ", "Premul ", "Unpremul"}; 761 SkBitmap bitmap; 762 SkAlphaType alphaTypes[] = { #list_of_alpha_types# 763 }; 764 SkDebugf("%18s%15s%17s%18s%19s\n", "Canonical", "Unknown", "Opaque", "Premul", "Unpremul"); 765 for (SkColorType colorType : { #list_of_color_types# 766 } ) { 767 for (SkAlphaType canonicalAlphaType : alphaTypes) { 768 SkColorTypeValidateAlphaType(colorType, kUnknown_SkAlphaType, &canonicalAlphaType ); 769 SkDebugf("%12s %9s ", colors[(int) colorType], alphas[(int) canonicalAlphaType ]); 770 for (SkAlphaType alphaType : alphaTypes) { 771 bitmap.setInfo(SkImageInfo::Make(4, 4, colorType, canonicalAlphaType)); 772 bool result = bitmap.setAlphaType(alphaType); 773 SkDebugf("%s %s ", result ? "true " : "false", alphas[(int) bitmap.alphaType()]); 774 } 775 SkDebugf("\n"); 776 } 777 } 778} 779## 780 781#SeeAlso Alpha_Type Color_Type Image_Info setInfo 782 783## 784 785# ------------------------------------------------------------------------------ 786 787#Method void* getPixels() const 788#In Property 789#Line # returns address of pixels ## 790#Populate 791 792#Example 793 SkBitmap bitmap; 794 bitmap.setInfo(SkImageInfo::MakeN32(4, 4, kPremul_SkAlphaType)); 795 bitmap.allocPixels(); 796 bitmap.eraseColor(0x00000000); 797 void* baseAddr = bitmap.getPixels(); 798 *(SkPMColor*)baseAddr = 0xFFFFFFFF; 799 SkDebugf("bitmap.getColor(0, 1) %c= 0x00000000\n", 800 bitmap.getColor(0, 1) == 0x00000000 ? '=' : '!'); 801 SkDebugf("bitmap.getColor(0, 0) %c= 0xFFFFFFFF\n", 802 bitmap.getColor(0, 0) == 0xFFFFFFFF ? '=' : '!'); 803#StdOut 804bitmap.getColor(0, 1) == 0x00000000 805bitmap.getColor(0, 0) == 0xFFFFFFFF 806## 807## 808 809#SeeAlso isNull drawsNothing 810 811## 812 813# ------------------------------------------------------------------------------ 814 815#Method size_t computeByteSize() const 816#In Utility 817#Line # returns size required for pixels ## 818#Populate 819 820#Example 821 SkBitmap bitmap; 822 for (int width : { 1, 1000, 1000000 } ) { 823 for (int height: { 1, 1000, 1000000 } ) { 824 SkImageInfo imageInfo = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType); 825 bitmap.setInfo(imageInfo, width * 5); 826 SkDebugf("width: %7d height: %7d computeByteSize: %13lld\n", width, height, 827 bitmap.computeByteSize()); 828 } 829 } 830#StdOut 831width: 1 height: 1 computeByteSize: 4 832width: 1 height: 1000 computeByteSize: 4999 833width: 1 height: 1000000 computeByteSize: 4999999 834width: 1000 height: 1 computeByteSize: 4000 835width: 1000 height: 1000 computeByteSize: 4999000 836width: 1000 height: 1000000 computeByteSize: 4999999000 837width: 1000000 height: 1 computeByteSize: 4000000 838width: 1000000 height: 1000 computeByteSize: 4999000000 839width: 1000000 height: 1000000 computeByteSize: 4999999000000 840## 841## 842 843#SeeAlso SkImageInfo::computeByteSize 844 845## 846 847# ------------------------------------------------------------------------------ 848 849#Method bool isImmutable() const 850#In Property 851#Line # returns true if pixels will not change ## 852#Populate 853 854#Example 855 SkBitmap original; 856 SkImageInfo info = SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType); 857 if (original.tryAllocPixels(info)) { 858 original.setImmutable(); 859 SkBitmap copy; 860 original.extractSubset(©, {5, 10, 15, 20}); 861 SkDebugf("original is " "%s" "immutable\n", original.isImmutable() ? "" : "not "); 862 SkDebugf("copy is " "%s" "immutable\n", copy.isImmutable() ? "" : "not "); 863 } 864#StdOut 865original is immutable 866copy is immutable 867## 868## 869 870#SeeAlso setImmutable SkPixelRef::isImmutable SkImage 871 872## 873 874# ------------------------------------------------------------------------------ 875 876#Method void setImmutable() 877#In Set 878#Line # marks that pixels will not change ## 879#Populate 880 881#Example 882#Description 883Triggers assert if SK_DEBUG is true, runs fine otherwise. 884## 885 SkBitmap bitmap; 886 bitmap.setInfo(SkImageInfo::MakeN32(4, 4, kPremul_SkAlphaType)); 887 bitmap.allocPixels(); 888 SkCanvas offscreen(bitmap); 889 SkDebugf("draw white\n"); 890 offscreen.clear(SK_ColorWHITE); 891 bitmap.setImmutable(); 892 SkDebugf("draw black\n"); 893 offscreen.clear(SK_ColorBLACK); 894## 895 896#SeeAlso isImmutable SkPixelRef::setImmutable SkImage 897 898## 899 900# ------------------------------------------------------------------------------ 901 902#Method bool isOpaque() const 903#In Property 904#Line # returns true if Image_Info describes opaque pixels ## 905#Populate 906 907#Example 908#Description 909 isOpaque ignores whether all pixels are opaque or not. 910## 911 const int height = 2; 912 const int width = 2; 913 SkBitmap bitmap; 914 bitmap.setInfo(SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType)); 915 for (int index = 0; index < 2; ++index) { 916 bitmap.allocPixels(); 917 bitmap.eraseColor(0x00000000); 918 SkDebugf("isOpaque: %s\n", bitmap.isOpaque() ? "true" : "false"); 919 bitmap.eraseColor(0xFFFFFFFF); 920 SkDebugf("isOpaque: %s\n", bitmap.isOpaque() ? "true" : "false"); 921 bitmap.setInfo(bitmap.info().makeAlphaType(kOpaque_SkAlphaType)); 922 } 923#StdOut 924isOpaque: false 925isOpaque: false 926isOpaque: true 927isOpaque: true 928## 929## 930 931#SeeAlso ComputeIsOpaque SkImageInfo::isOpaque 932 933## 934 935# ------------------------------------------------------------------------------ 936 937#Method bool isVolatile() const 938#In Property 939#Line # returns true if pixels should not be cached ## 940#Populate 941 942#Example 943 SkBitmap original; 944 SkImageInfo info = SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType); 945 if (original.tryAllocPixels(info)) { 946 original.setIsVolatile(true); 947 SkBitmap copy; 948 original.extractSubset(©, {5, 10, 15, 20}); 949 SkDebugf("original is " "%s" "volatile\n", original.isVolatile() ? "" : "not "); 950 SkDebugf("copy is " "%s" "volatile\n", copy.isImmutable() ? "" : "not "); 951 } 952#StdOut 953original is volatile 954copy is not volatile 955## 956## 957 958#SeeAlso setIsVolatile 959 960## 961 962# ------------------------------------------------------------------------------ 963 964#Method void setIsVolatile(bool isVolatile) 965#In Set 966#Line # marks if pixels should not be cached ## 967#Populate 968 969#Example 970#Height 20 971 SkBitmap bitmap; 972 bitmap.setInfo(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType)); 973 bitmap.allocPixels(); 974 bitmap.eraseColor(SK_ColorRED); 975 canvas->scale(16, 16); 976 canvas->drawBitmap(bitmap, 0, 0); 977 *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorBLUE); 978 canvas->drawBitmap(bitmap, 2, 0); 979 bitmap.setIsVolatile(true); 980 *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorGREEN); 981 canvas->drawBitmap(bitmap, 4, 0); 982## 983 984#SeeAlso isVolatile 985 986## 987 988# ------------------------------------------------------------------------------ 989 990#Method void reset() 991#In Constructors 992#Line # sets to default values, releases pixel ownership ## 993#Populate 994 995#Example 996 SkBitmap bitmap; 997 bitmap.setInfo(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType)); 998 bitmap.allocPixels(); 999 SkDebugf("width:%d height:%d isNull:%s\n", bitmap.width(), bitmap.height(), 1000 bitmap.isNull() ? "true" : "false"); 1001 bitmap.reset(); 1002 SkDebugf("width:%d height:%d isNull:%s\n", bitmap.width(), bitmap.height(), 1003 bitmap.isNull() ? "true" : "false"); 1004#StdOut 1005width:1 height:1 isNull:false 1006width:0 height:0 isNull:true 1007## 1008## 1009 1010#SeeAlso SkBitmap() SkAlphaType SkColorType 1011 1012## 1013 1014# ------------------------------------------------------------------------------ 1015 1016#Method static bool ComputeIsOpaque(const SkBitmap& bm) 1017#In Utility 1018#Line # returns true if all pixels are opaque ## 1019#Populate 1020 1021#Example 1022 SkBitmap bitmap; 1023 bitmap.setInfo(SkImageInfo::Make(2, 2, kN32_SkColorType, kPremul_SkAlphaType)); 1024 for (int index = 0; index < 2; ++index) { 1025 bitmap.allocPixels(); 1026 bitmap.eraseColor(0x00000000); 1027 SkDebugf("computeIsOpaque: %s\n", SkBitmap::ComputeIsOpaque(bitmap) ? "true" : "false"); 1028 bitmap.eraseColor(0xFFFFFFFF); 1029 SkDebugf("computeIsOpaque: %s\n", SkBitmap::ComputeIsOpaque(bitmap) ? "true" : "false"); 1030 bitmap.setInfo(bitmap.info().makeAlphaType(kOpaque_SkAlphaType)); 1031 } 1032#StdOut 1033computeIsOpaque: false 1034computeIsOpaque: true 1035computeIsOpaque: false 1036computeIsOpaque: true 1037## 1038## 1039 1040#SeeAlso isOpaque Color_Type Alpha 1041 1042## 1043 1044# ------------------------------------------------------------------------------ 1045 1046#Method void getBounds(SkRect* bounds) const 1047#In Property 1048#Line # returns width() and height() as Rectangle ## 1049#Populate 1050 1051#Example 1052#Height 160 1053#Image 3 1054 SkRect bounds; 1055 source.getBounds(&bounds); 1056 bounds.offset(100, 100); 1057 SkPaint paint; 1058 paint.setColor(SK_ColorGRAY); 1059 canvas->scale(.25f, .25f); 1060 canvas->drawRect(bounds, paint); 1061 canvas->drawBitmap(source, 40, 40); 1062## 1063 1064#SeeAlso bounds() 1065 1066## 1067 1068# ------------------------------------------------------------------------------ 1069 1070#Method void getBounds(SkIRect* bounds) const 1071#Populate 1072 1073#Example 1074#Image 3 1075 SkIRect bounds; 1076 source.getBounds(&bounds); 1077 bounds.inset(100, 100); 1078 SkBitmap bitmap; 1079 source.extractSubset(&bitmap, bounds); 1080 canvas->scale(.5f, .5f); 1081 canvas->drawBitmap(bitmap, 10, 10); 1082## 1083 1084#SeeAlso bounds() 1085 1086## 1087 1088# ------------------------------------------------------------------------------ 1089 1090#Method SkIRect bounds() const 1091#In Property 1092#Line # returns width() and height() as Rectangle ## 1093#Populate 1094 1095#Example 1096#Height 64 1097#Image 4 1098 canvas->scale(.5f, .5f); 1099 SkIRect bounds = source.bounds(); 1100 for (int x : { 0, bounds.width() } ) { 1101 for (int y : { 0, bounds.height() } ) { 1102 canvas->drawBitmap(source, x, y); 1103 } 1104 } 1105## 1106 1107#SeeAlso getBounds 1108 1109## 1110 1111# ------------------------------------------------------------------------------ 1112 1113#Method SkISize dimensions() const 1114#In Property 1115#Line # returns width() and height() ## 1116#Populate 1117 1118#Example 1119 SkBitmap bitmap; 1120 bitmap.setInfo(SkImageInfo::MakeN32(33, 55, kOpaque_SkAlphaType)); 1121 SkISize dimensions = bitmap.dimensions(); 1122 SkRect bounds; 1123 bitmap.getBounds(&bounds); 1124 SkRect dimensionsAsBounds = SkRect::Make(dimensions); 1125 SkDebugf("dimensionsAsBounds %c= bounds\n", dimensionsAsBounds == bounds ? '=' : '!'); 1126## 1127 1128#SeeAlso height width 1129 1130## 1131 1132# ------------------------------------------------------------------------------ 1133 1134#Method SkIRect getSubset() const 1135#In Property 1136#Line # returns bounds offset by origin ## 1137#Populate 1138 1139#Example 1140#Image 3 1141 SkIRect bounds; 1142 source.getBounds(&bounds); 1143 bounds.inset(100, 100); 1144 SkBitmap subset; 1145 source.extractSubset(&subset, bounds); 1146 SkIRect r = source.getSubset(); 1147 SkDebugf("source: %d, %d, %d, %d\n", r.fLeft, r.fTop, r.fRight, r.fBottom); 1148 r = subset.getSubset(); 1149 SkDebugf("subset: %d, %d, %d, %d\n", r.fLeft, r.fTop, r.fRight, r.fBottom); 1150#StdOut 1151source: 0, 0, 512, 512 1152subset: 100, 100, 412, 412 1153## 1154## 1155 1156#SeeAlso extractSubset getBounds 1157 1158## 1159 1160# ------------------------------------------------------------------------------ 1161 1162#Method bool setInfo(const SkImageInfo& imageInfo, size_t rowBytes = 0) 1163#In Set 1164#Line # sets height, width, Color_Type, and so on, releasing pixels ## 1165Sets width, height, Alpha_Type, Color_Type, Color_Space, and optional 1166rowBytes. Frees pixels, and returns true if successful. 1167 1168imageInfo.alphaType() may be altered to a value permitted by imageInfo.colorSpace(). 1169If imageInfo.colorType() is kUnknown_SkColorType, imageInfo.alphaType() is 1170set to kUnknown_SkAlphaType. 1171If imageInfo.colorType() is kAlpha_8_SkColorType and imageInfo.alphaType() is 1172kUnpremul_SkAlphaType, imageInfo.alphaType() is replaced by kPremul_SkAlphaType. 1173If imageInfo.colorType() is kRGB_565_SkColorType or kGray_8_SkColorType, 1174imageInfo.alphaType() is set to kOpaque_SkAlphaType. 1175If imageInfo.colorType() is kARGB_4444_SkColorType, kRGBA_8888_SkColorType, 1176kBGRA_8888_SkColorType, or kRGBA_F16_SkColorType: imageInfo.alphaType() remains 1177unchanged. 1178 1179rowBytes must equal or exceed imageInfo.minRowBytes(). If imageInfo.colorSpace() is 1180kUnknown_SkColorType, rowBytes is ignored and treated as zero; for all other 1181Color_Space values, rowBytes of zero is treated as imageInfo.minRowBytes(). 1182 1183Calls reset() and returns false if: 1184#List 1185# rowBytes exceeds 31 bits ## 1186# imageInfo.width() is negative ## 1187# imageInfo.height() is negative ## 1188# rowBytes is positive and less than imageInfo.width() times imageInfo.bytesPerPixel() ## 1189## 1190 1191#Param imageInfo contains width, height, Alpha_Type, Color_Type, Color_Space ## 1192#Param rowBytes imageInfo.minRowBytes() or larger; or zero ## 1193 1194#Return true if Image_Info set successfully ## 1195 1196#Example 1197#Height 96 1198###^ 1199SkBitmap bitmap; 1200bitmap.setInfo(SkImageInfo::MakeN32(44, 16, kOpaque_SkAlphaType)); 1201bitmap.allocPixels(); 1202bitmap.eraseColor(SK_ColorGREEN); 1203SkCanvas offscreen(bitmap); 1204SkPaint paint; 1205offscreen.drawString("!@#$%", 0, 12, paint); 1206canvas->scale(6, 6); 1207canvas->drawBitmap(bitmap, 0, 0); 1208^^^# 1209## 1210 1211#SeeAlso Alpha_Type Color_Type Color_Space height rowBytes width 1212 1213## 1214 1215# ------------------------------------------------------------------------------ 1216 1217#Enum AllocFlags 1218#Line # zero pixel memory ## 1219#Code 1220#Populate 1221## 1222 1223AllocFlags provides the option to zero pixel memory when allocated. 1224 1225#Const kZeroPixels_AllocFlag 1 1226#Line # zero pixel memory ## 1227 Instructs tryAllocPixelsFlags and allocPixelsFlags to zero pixel memory. 1228## 1229 1230#NoExample 1231## 1232 1233#SeeAlso tryAllocPixelsFlags allocPixelsFlags erase eraseColor 1234 1235## 1236 1237# ------------------------------------------------------------------------------ 1238#Subtopic Allocate 1239#Line # allocates storage for pixels ## 1240## 1241 1242#Method bool tryAllocPixelsFlags(const SkImageInfo& info, uint32_t flags) 1243#In Allocate 1244#Line # allocates pixels from Image_Info with options if possible ## 1245#Populate 1246 1247#Example 1248 SkBitmap bitmap; 1249 if (!bitmap.tryAllocPixelsFlags(SkImageInfo::MakeN32(10000, 10000, kOpaque_SkAlphaType), 1250 SkBitmap::kZeroPixels_AllocFlag)) { 1251 SkDebugf("bitmap allocation failed!\n"); 1252 } else { 1253 SkDebugf("bitmap allocation succeeded!\n"); 1254 } 1255#StdOut 1256bitmap allocation succeeded! 1257## 1258## 1259 1260#SeeAlso allocPixelsFlags tryAllocPixels SkMallocPixelRef::MakeZeroed 1261 1262## 1263 1264# ------------------------------------------------------------------------------ 1265 1266#Method void allocPixelsFlags(const SkImageInfo& info, uint32_t flags) 1267#In Allocate 1268#Line # allocates pixels from Image_Info with options, or aborts ## 1269#Populate 1270 1271#Example 1272#Height 128 1273#Description 1274Text is drawn on a transparent background; drawing the bitmap a second time 1275lets the first draw show through. 1276## 1277###^ 1278SkBitmap bitmap; 1279bitmap.allocPixelsFlags(SkImageInfo::MakeN32(44, 16, kPremul_SkAlphaType), 1280 SkBitmap::kZeroPixels_AllocFlag); 1281SkCanvas offscreen(bitmap); 1282SkPaint paint; 1283offscreen.drawString("!@#$%", 0, 12, paint); 1284canvas->scale(6, 6); 1285canvas->drawBitmap(bitmap, 0, 0); 1286canvas->drawBitmap(bitmap, 8, 8); 1287^^^# 1288## 1289 1290#SeeAlso tryAllocPixelsFlags allocPixels SkMallocPixelRef::MakeZeroed 1291 1292## 1293 1294# ------------------------------------------------------------------------------ 1295 1296#Method bool tryAllocPixels(const SkImageInfo& info, size_t rowBytes) 1297#In Allocate 1298#Line # allocates pixels from Image_Info if possible ## 1299#Populate 1300 1301#Example 1302#Image 3 1303SkBitmap bitmap; 1304SkImageInfo info = SkImageInfo::Make(64, 256, kGray_8_SkColorType, kOpaque_SkAlphaType); 1305if (bitmap.tryAllocPixels(info, 0)) { 1306 SkCanvas offscreen(bitmap); 1307 offscreen.scale(.5f, .5f); 1308 for (int x : { 0, 64, 128, 192 } ) { 1309 offscreen.drawBitmap(source, -x, 0); 1310 canvas->drawBitmap(bitmap, x, 0); 1311 } 1312} 1313## 1314 1315#SeeAlso tryAllocPixelsFlags allocPixels SkMallocPixelRef::MakeAllocate 1316 1317## 1318 1319# ------------------------------------------------------------------------------ 1320 1321#Method void allocPixels(const SkImageInfo& info, size_t rowBytes) 1322#In Allocate 1323#Line # allocates pixels from Image_Info, or aborts ## 1324#Populate 1325 1326#Example 1327#Image 3 1328SkBitmap bitmap; 1329SkImageInfo info = SkImageInfo::Make(256, 64, kGray_8_SkColorType, kOpaque_SkAlphaType); 1330bitmap.allocPixels(info, info.width() * info.bytesPerPixel() + 64); 1331SkCanvas offscreen(bitmap); 1332offscreen.scale(.5f, .5f); 1333for (int y : { 0, 64, 128, 192 } ) { 1334 offscreen.drawBitmap(source, 0, -y); 1335 canvas->drawBitmap(bitmap, 0, y); 1336} 1337## 1338 1339#SeeAlso tryAllocPixels allocPixelsFlags SkMallocPixelRef::MakeAllocate 1340 1341## 1342 1343# ------------------------------------------------------------------------------ 1344 1345#Method bool tryAllocPixels(const SkImageInfo& info) 1346#Populate 1347 1348#Example 1349#Image 3 1350SkBitmap bitmap; 1351if (bitmap.tryAllocPixels(SkImageInfo::Make(64, 64, kGray_8_SkColorType, kOpaque_SkAlphaType))) { 1352 SkCanvas offscreen(bitmap); 1353 offscreen.scale(.25f, .5f); 1354 for (int y : { 0, 64, 128, 192 } ) { 1355 offscreen.drawBitmap(source, -y, -y); 1356 canvas->drawBitmap(bitmap, y, y); 1357 } 1358} 1359## 1360 1361#SeeAlso tryAllocPixelsFlags allocPixels SkMallocPixelRef::MakeAllocate 1362 1363## 1364 1365# ------------------------------------------------------------------------------ 1366 1367#Method void allocPixels(const SkImageInfo& info) 1368#Populate 1369 1370#Example 1371#Image 4 1372SkBitmap bitmap; 1373bitmap.allocPixels(SkImageInfo::Make(64, 64, kGray_8_SkColorType, kOpaque_SkAlphaType)); 1374SkCanvas offscreen(bitmap); 1375offscreen.scale(.5f, .5f); 1376for (int y : { 0, 64, 128, 192 } ) { 1377 offscreen.drawBitmap(source, -y, -y); 1378 canvas->drawBitmap(bitmap, y, y); 1379} 1380## 1381 1382#SeeAlso tryAllocPixels allocPixelsFlags SkMallocPixelRef::MakeAllocate 1383 1384## 1385 1386# ------------------------------------------------------------------------------ 1387 1388#Method bool tryAllocN32Pixels(int width, int height, bool isOpaque = false) 1389#In Allocate 1390#Line # allocates compatible ARGB pixels if possible ## 1391#Populate 1392 1393#Example 1394#Height 160 1395 SkBitmap bitmap; 1396 if (bitmap.tryAllocN32Pixels(80, 80)) { 1397 bitmap.eraseColor(SK_ColorTRANSPARENT); 1398 bitmap.erase(0x7f3f7fff, SkIRect::MakeWH(50, 30)); 1399 bitmap.erase(0x3f7fff3f, SkIRect::MakeXYWH(20, 10, 50, 30)); 1400 bitmap.erase(0x5fff3f7f, SkIRect::MakeXYWH(40, 20, 50, 30)); 1401 canvas->drawBitmap(bitmap, 0, 0); 1402 for (int x : { 0, 30, 60, 90 } ) { 1403 canvas->drawBitmap(bitmap, x, 70); 1404 } 1405 } 1406## 1407 1408#SeeAlso tryAllocPixels allocN32Pixels SkMallocPixelRef::MakeAllocate 1409 1410## 1411 1412# ------------------------------------------------------------------------------ 1413 1414#Method void allocN32Pixels(int width, int height, bool isOpaque = false) 1415#In Allocate 1416#Line # allocates compatible ARGB pixels, or aborts ## 1417#Populate 1418 1419#Example 1420 SkRandom random; 1421 SkBitmap bitmap; 1422 bitmap.allocN32Pixels(64, 64); 1423 bitmap.eraseColor(SK_ColorTRANSPARENT); 1424 for (int y = 0; y < 256; y += 64) { 1425 for (int x = 0; x < 256; x += 64) { 1426 SkColor color = random.nextU(); 1427 uint32_t w = random.nextRangeU(4, 32); 1428 uint32_t cx = random.nextRangeU(0, 64 - w); 1429 uint32_t h = random.nextRangeU(4, 32); 1430 uint32_t cy = random.nextRangeU(0, 64 - h); 1431 bitmap.erase(color, SkIRect::MakeXYWH(cx, cy, w, h)); 1432 canvas->drawBitmap(bitmap, x, y); 1433 } 1434 } 1435## 1436 1437#SeeAlso allocPixels tryAllocN32Pixels SkMallocPixelRef::MakeAllocate 1438 1439## 1440 1441# ------------------------------------------------------------------------------ 1442 1443#Method bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, 1444 void (*releaseProc)(void* addr, void* context), void* context) 1445#In Allocate 1446#Line # creates Pixel_Ref, with optional release function ## 1447#Populate 1448 1449#Example 1450#Description 1451releaseProc is called immediately because rowBytes is too small for Pixel_Ref. 1452## 1453#Function 1454static void releaseProc(void* addr, void* ) { 1455 SkDebugf("releaseProc called\n"); 1456 delete[] (uint32_t*) addr; 1457} 1458 1459## 1460 1461void draw(SkCanvas* canvas) { 1462 SkBitmap bitmap; 1463 void* pixels = new uint32_t[8 * 8]; 1464 SkImageInfo info = SkImageInfo::MakeN32(8, 8, kOpaque_SkAlphaType); 1465 SkDebugf("before installPixels\n"); 1466 bool installed = bitmap.installPixels(info, pixels, 16, releaseProc, nullptr); 1467 SkDebugf("install " "%s" "successful\n", installed ? "" : "not "); 1468} 1469#StdOut 1470before installPixels 1471releaseProc called 1472install not successful 1473## 1474## 1475 1476#SeeAlso allocPixels 1477 1478## 1479 1480# ------------------------------------------------------------------------------ 1481 1482#Method bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) 1483#Populate 1484 1485#Example 1486#Bug 7079 1487#Description 1488GPU does not support kUnpremul_SkAlphaType, does not assert that it does not. 1489## 1490void draw(SkCanvas* canvas) { 1491 SkRandom random; 1492 SkBitmap bitmap; 1493 const int width = 8; 1494 const int height = 8; 1495 uint32_t pixels[width * height]; 1496 for (unsigned x = 0; x < width * height; ++x) { 1497 pixels[x] = random.nextU(); 1498 } 1499 SkImageInfo info = SkImageInfo::MakeN32(width, height, kUnpremul_SkAlphaType); 1500 if (bitmap.installPixels(info, pixels, info.minRowBytes())) { 1501 canvas->scale(32, 32); 1502 canvas->drawBitmap(bitmap, 0, 0); 1503 } 1504} 1505## 1506 1507#SeeAlso allocPixels 1508 1509## 1510 1511# ------------------------------------------------------------------------------ 1512 1513#Method bool installPixels(const SkPixmap& pixmap) 1514#Populate 1515 1516#Example 1517#Description 1518Draw a five by five bitmap, and draw it again with a center white pixel. 1519## 1520#Height 64 1521 uint8_t storage[][5] = {{ 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 }, 1522 { 0xAC, 0xA8, 0x89, 0x47, 0x87 }, 1523 { 0x4B, 0x25, 0x25, 0x25, 0x46 }, 1524 { 0x90, 0x81, 0x25, 0x41, 0x33 }, 1525 { 0x75, 0x55, 0x44, 0x20, 0x00 }}; 1526 SkImageInfo imageInfo = SkImageInfo::Make(5, 5, kGray_8_SkColorType, kOpaque_SkAlphaType); 1527 SkPixmap pixmap(imageInfo, storage[0], sizeof(storage) / 5); 1528 SkBitmap bitmap; 1529 bitmap.installPixels(pixmap); 1530 canvas->scale(10, 10); 1531 canvas->drawBitmap(bitmap, 0, 0); 1532 *pixmap.writable_addr8(2, 2) = 0xFF; 1533 bitmap.installPixels(pixmap); 1534 canvas->drawBitmap(bitmap, 10, 0); 1535## 1536 1537#SeeAlso allocPixels 1538 1539## 1540 1541# ------------------------------------------------------------------------------ 1542#Subtopic Pixels 1543#Line # read and write pixel values ## 1544## 1545 1546#Method void setPixels(void* pixels) 1547#In Pixels 1548#Line # sets Pixel_Ref without an offset ## 1549#Populate 1550 1551#Example 1552#Height 50 1553 uint8_t set1[5] = { 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 }; 1554 uint8_t set2[5] = { 0xAC, 0xA8, 0x89, 0x47, 0x87 }; 1555 SkBitmap bitmap; 1556 bitmap.installPixels(SkImageInfo::Make(5, 1, kGray_8_SkColorType, kOpaque_SkAlphaType), set1, 5); 1557 canvas->scale(10, 50); 1558 canvas->drawBitmap(bitmap, 0, 0); 1559 bitmap.setPixels(set2); 1560 canvas->drawBitmap(bitmap, 10, 0); 1561## 1562 1563#SeeAlso installPixels allocPixels 1564 1565## 1566 1567# ------------------------------------------------------------------------------ 1568 1569#Method bool tryAllocPixels() 1570#In Allocate 1571#Populate 1572 1573#Example 1574#Height 50 1575#Description 1576Bitmap hosts and draws gray values in set1. tryAllocPixels replaces Pixel_Ref 1577and erases it to black, but does not alter set1. setPixels replaces black 1578Pixel_Ref with set1. 1579## 1580 uint8_t set1[5] = { 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 }; 1581 SkBitmap bitmap; 1582 bitmap.installPixels(SkImageInfo::Make(5, 1, kGray_8_SkColorType, kOpaque_SkAlphaType), set1, 5); 1583 canvas->scale(10, 50); 1584 canvas->drawBitmap(bitmap, 0, 0); 1585 if (bitmap.tryAllocPixels()) { 1586 bitmap.eraseColor(SK_ColorBLACK); 1587 canvas->drawBitmap(bitmap, 8, 0); 1588 bitmap.setPixels(set1); 1589 canvas->drawBitmap(bitmap, 16, 0); 1590 } 1591## 1592 1593#SeeAlso allocPixels installPixels setPixels 1594 1595## 1596 1597# ------------------------------------------------------------------------------ 1598 1599#Method void allocPixels() 1600#In Allocate 1601#Populate 1602 1603#Example 1604#Height 50 1605#Description 1606Bitmap hosts and draws gray values in set1. allocPixels replaces Pixel_Ref 1607and erases it to black, but does not alter set1. setPixels replaces black 1608Pixel_Ref with set2. 1609## 1610 uint8_t set1[5] = { 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 }; 1611 uint8_t set2[5] = { 0xAC, 0xA8, 0x89, 0x47, 0x87 }; 1612 SkBitmap bitmap; 1613 bitmap.installPixels(SkImageInfo::Make(5, 1, kGray_8_SkColorType, kOpaque_SkAlphaType), set1, 5); 1614 canvas->scale(10, 50); 1615 canvas->drawBitmap(bitmap, 0, 0); 1616 bitmap.allocPixels(); 1617 bitmap.eraseColor(SK_ColorBLACK); 1618 canvas->drawBitmap(bitmap, 8, 0); 1619 bitmap.setPixels(set2); 1620 canvas->drawBitmap(bitmap, 16, 0); 1621## 1622 1623#SeeAlso tryAllocPixels installPixels setPixels 1624 1625## 1626 1627# ------------------------------------------------------------------------------ 1628 1629#Method bool tryAllocPixels(Allocator* allocator) 1630#Populate 1631 1632#Example 1633#Height 100 1634#Description 1635HeapAllocator limits the maximum size of Bitmap to two gigabytes. Using 1636a custom allocator, this limitation may be relaxed. This example can be 1637modified to allocate an eight gigabyte Bitmap on a 64-bit platform with 1638sufficient memory. 1639## 1640#Function 1641class LargePixelRef : public SkPixelRef { 1642public: 1643 LargePixelRef(const SkImageInfo& info, char* storage, size_t rowBytes) 1644 : SkPixelRef(info.width(), info.height(), storage, rowBytes) { 1645 } 1646 1647 ~LargePixelRef() override { 1648 delete[] (char* ) this->pixels(); 1649 } 1650}; 1651 1652class LargeAllocator : public SkBitmap::Allocator { 1653public: 1654 bool allocPixelRef(SkBitmap* bitmap) override { 1655 const SkImageInfo& info = bitmap->info(); 1656 uint64_t rowBytes = info.minRowBytes64(); 1657 uint64_t size = info.height() * rowBytes; 1658 char* addr = new char[size]; 1659 if (nullptr == addr) { 1660 return false; 1661 } 1662 sk_sp<SkPixelRef> pr = sk_sp<SkPixelRef>(new LargePixelRef(info, addr, rowBytes)); 1663 if (!pr) { 1664 return false; 1665 } 1666 bitmap->setPixelRef(std::move(pr), 0, 0); 1667 return true; 1668 } 1669}; 1670 1671## 1672 1673void draw(SkCanvas* canvas) { 1674 LargeAllocator largeAllocator; 1675 SkBitmap bitmap; 1676 int width = 100; // make this 20000 1677 int height = 100; // and this 100000 to allocate 8 gigs on a 64-bit platform 1678 bitmap.setInfo(SkImageInfo::MakeN32(width, height, kOpaque_SkAlphaType)); 1679 if (bitmap.tryAllocPixels(&largeAllocator)) { 1680 bitmap.eraseColor(0xff55aa33); 1681 canvas->drawBitmap(bitmap, 0, 0); 1682 } 1683} 1684 1685## 1686 1687#SeeAlso allocPixels Allocator Pixel_Ref 1688 1689## 1690 1691# ------------------------------------------------------------------------------ 1692 1693#Method void allocPixels(Allocator* allocator) 1694#Populate 1695 1696#Example 1697#Height 32 1698#Function 1699class TinyAllocator : public SkBitmap::Allocator { 1700public: 1701 bool allocPixelRef(SkBitmap* bitmap) override { 1702 const SkImageInfo& info = bitmap->info(); 1703 if (info.height() * info.minRowBytes() > sizeof(storage)) { 1704 return false; 1705 } 1706 sk_sp<SkPixelRef> pr = sk_sp<SkPixelRef>( 1707 new SkPixelRef(info.width(), info.height(), storage, info.minRowBytes())); 1708 bitmap->setPixelRef(std::move(pr), 0, 0); 1709 return true; 1710 } 1711 1712 char storage[16]; 1713}; 1714 1715## 1716 1717void draw(SkCanvas* canvas) { 1718 TinyAllocator tinyAllocator; 1719 SkBitmap bitmap; 1720 bitmap.setInfo(SkImageInfo::MakeN32(2, 2, kOpaque_SkAlphaType)); 1721 if (bitmap.tryAllocPixels(&tinyAllocator)) { 1722 bitmap.eraseColor(0xff55aa33); 1723 bitmap.erase(0xffaa3355, SkIRect::MakeXYWH(1, 1, 1, 1)); 1724 canvas->scale(16, 16); 1725 canvas->drawBitmap(bitmap, 0, 0); 1726 } 1727} 1728## 1729 1730#SeeAlso allocPixels Allocator Pixel_Ref 1731 1732## 1733 1734# ------------------------------------------------------------------------------ 1735 1736#Method SkPixelRef* pixelRef() const 1737#In Property 1738#Line # returns Pixel_Ref, or nullptr ## 1739#Populate 1740 1741#Example 1742#Image 3 1743 SkBitmap subset; 1744 source.extractSubset(&subset, SkIRect::MakeXYWH(32, 64, 128, 256)); 1745 SkDebugf("src ref %c= sub ref\n", source.pixelRef() == subset.pixelRef() ? '=' : '!'); 1746 SkDebugf("src pixels %c= sub pixels\n", source.getPixels() == subset.getPixels() ? '=' : '!'); 1747 SkDebugf("src addr %c= sub addr\n", source.getAddr(32, 64) == subset.getAddr(0, 0) ? '=' : '!'); 1748## 1749 1750#SeeAlso getPixels getAddr 1751 1752## 1753 1754# ------------------------------------------------------------------------------ 1755 1756#Method SkIPoint pixelRefOrigin() const 1757#In Property 1758#Line # returns offset within Pixel_Ref ## 1759#Populate 1760 1761#Example 1762#Image 3 1763 SkBitmap subset; 1764 source.extractSubset(&subset, SkIRect::MakeXYWH(32, 64, 128, 256)); 1765 SkIPoint sourceOrigin = source.pixelRefOrigin(); 1766 SkIPoint subsetOrigin = subset.pixelRefOrigin(); 1767 SkDebugf("source origin: %d, %d\n", sourceOrigin.fX, sourceOrigin.fY); 1768 SkDebugf("subset origin: %d, %d\n", subsetOrigin.fX, subsetOrigin.fY); 1769#StdOut 1770source origin: 0, 0 1771subset origin: 32, 64 1772## 1773## 1774 1775#SeeAlso SkPixelRef getSubset setPixelRef 1776 1777## 1778 1779# ------------------------------------------------------------------------------ 1780#Subtopic Set 1781#Line # updates values and attributes ## 1782## 1783 1784#Method void setPixelRef(sk_sp<SkPixelRef> pixelRef, int dx, int dy) 1785#In Set 1786#Line # sets Pixel_Ref and offset ## 1787#Populate 1788 1789#Example 1790#Height 140 1791#Image 5 1792#Description 1793Treating 32-bit data as 8-bit data is unlikely to produce useful results. 1794## 1795 SkBitmap bitmap; 1796 bitmap.setInfo(SkImageInfo::Make(source.width() - 5, source.height() - 5, 1797 kGray_8_SkColorType, kOpaque_SkAlphaType), source.rowBytes()); 1798 bitmap.setPixelRef(sk_ref_sp(source.pixelRef()), 5, 5); 1799 canvas->drawBitmap(bitmap, 10, 10); 1800## 1801 1802#SeeAlso setInfo 1803 1804## 1805 1806# ------------------------------------------------------------------------------ 1807 1808#Method bool readyToDraw() const 1809#In Utility 1810#Line # returns true if address of pixels is not nullptr ## 1811#Populate 1812 1813#Example 1814#Image 5 1815#Height 160 1816 if (source.readyToDraw()) { 1817 canvas->drawBitmap(source, 10, 10); 1818 } 1819## 1820 1821#SeeAlso getPixels drawsNothing 1822 1823## 1824 1825# ------------------------------------------------------------------------------ 1826 1827#Method uint32_t getGenerationID() const 1828#In Utility 1829#Line # returns unique ID ## 1830#Populate 1831 1832#Example 1833 SkBitmap bitmap; 1834 SkDebugf("empty id %u\n", bitmap.getGenerationID()); 1835 bitmap.allocPixels(SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType)); 1836 SkDebugf("alloc id %u\n", bitmap.getGenerationID()); 1837 bitmap.eraseColor(SK_ColorRED); 1838 SkDebugf("erase id %u\n", bitmap.getGenerationID()); 1839#StdOut 1840#Volatile 1841empty id 0 1842alloc id 4 1843erase id 6 1844## 1845## 1846 1847#SeeAlso notifyPixelsChanged Pixel_Ref 1848 1849## 1850 1851# ------------------------------------------------------------------------------ 1852 1853#Method void notifyPixelsChanged() const 1854#In Pixels 1855#Line # marks pixels as changed, altering the unique ID ## 1856#Populate 1857 1858#Example 1859#Height 20 1860 SkBitmap bitmap; 1861 bitmap.setInfo(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType)); 1862 bitmap.allocPixels(); 1863 bitmap.eraseColor(SK_ColorRED); 1864 canvas->scale(16, 16); 1865 canvas->drawBitmap(bitmap, 0, 0); 1866 *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorBLUE); 1867 canvas->drawBitmap(bitmap, 2, 0); 1868 bitmap.notifyPixelsChanged(); 1869 *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorGREEN); 1870 canvas->drawBitmap(bitmap, 4, 0); 1871## 1872 1873#SeeAlso getGenerationID isVolatile Pixel_Ref 1874 1875## 1876 1877# ------------------------------------------------------------------------------ 1878#Subtopic Draw 1879#Line # sets pixels to Color ## 1880## 1881 1882#Method void eraseColor(SkColor c) const 1883#In Draw 1884#Line # writes Color to pixels ## 1885#Populate 1886 1887#Example 1888#Height 20 1889 SkBitmap bitmap; 1890 bitmap.allocPixels(SkImageInfo::MakeN32(1, 1, kOpaque_SkAlphaType)); 1891 bitmap.eraseColor(SK_ColorRED); 1892 canvas->scale(16, 16); 1893 canvas->drawBitmap(bitmap, 0, 0); 1894## 1895 1896#SeeAlso eraseARGB erase 1897 1898## 1899 1900# ------------------------------------------------------------------------------ 1901 1902#Method void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const 1903#In Draw 1904#Line # writes Color to pixels ## 1905#Populate 1906 1907#Example 1908#Height 80 1909 SkBitmap bitmap; 1910 bitmap.allocPixels(SkImageInfo::MakeN32(1, 1, kPremul_SkAlphaType)); 1911 bitmap.eraseARGB(0x7f, 0xff, 0x7f, 0x3f); 1912 canvas->scale(50, 50); 1913 canvas->drawBitmap(bitmap, 0, 0); 1914 canvas->drawBitmap(bitmap, .5f, .5f); 1915## 1916 1917#SeeAlso eraseColor erase 1918 1919## 1920 1921# ------------------------------------------------------------------------------ 1922 1923#Method void erase(SkColor c, const SkIRect& area) const 1924#In Draw 1925#Line # writes Color to rectangle of pixels ## 1926#Populate 1927 1928#Example 1929#Height 70 1930 SkBitmap bitmap; 1931 bitmap.allocPixels(SkImageInfo::MakeN32(2, 2, kPremul_SkAlphaType)); 1932 bitmap.erase(0x7fff7f3f, SkIRect::MakeWH(1, 1)); 1933 bitmap.erase(0x7f7f3fff, SkIRect::MakeXYWH(0, 1, 1, 1)); 1934 bitmap.erase(0x7f3fff7f, SkIRect::MakeXYWH(1, 0, 1, 1)); 1935 bitmap.erase(0x7f1fbf5f, SkIRect::MakeXYWH(1, 1, 1, 1)); 1936 canvas->scale(25, 25); 1937 canvas->drawBitmap(bitmap, 0, 0); 1938 canvas->drawBitmap(bitmap, .5f, .5f); 1939 1940## 1941 1942#SeeAlso eraseColor eraseARGB SkCanvas::drawRect 1943 1944## 1945 1946# ------------------------------------------------------------------------------ 1947 1948#Method SkColor getColor(int x, int y) const 1949#In Property 1950#In Pixels 1951#Line # returns one pixel as Unpremultiplied Color ## 1952#Populate 1953 1954#Example 1955 const int w = 4; 1956 const int h = 4; 1957 SkColor colors[][w] = { 1958 { 0x00000000, 0x2a0e002a, 0x55380055, 0x7f7f007f }, 1959 { 0x2a000e2a, 0x551c1c55, 0x7f542a7f, 0xaaaa38aa }, 1960 { 0x55003855, 0x7f2a547f, 0xaa7171aa, 0xd4d48dd4 }, 1961 { 0x7f007f7f, 0xaa38aaaa, 0xd48dd4d4, 0xffffffff } 1962 }; 1963 SkDebugf("Premultiplied:\n"); 1964 for (int y = 0; y < h; ++y) { 1965 SkDebugf("(0, %d) ", y); 1966 for (int x = 0; x < w; ++x) { 1967 SkDebugf("0x%08x%c", colors[y][x], x == w - 1 ? '\n' : ' '); 1968 } 1969 } 1970 SkPixmap pixmap(SkImageInfo::MakeN32(w, h, kPremul_SkAlphaType), colors, w * 4); 1971 SkBitmap bitmap; 1972 bitmap.installPixels(pixmap); 1973 SkDebugf("Unpremultiplied:\n"); 1974 for (int y = 0; y < h; ++y) { 1975 SkDebugf("(0, %d) ", y); 1976 for (int x = 0; x < w; ++x) { 1977 SkDebugf("0x%08x%c", bitmap.getColor(x, y), x == w - 1 ? '\n' : ' '); 1978 } 1979 } 1980#StdOut 1981Premultiplied: 1982(0, 0) 0x00000000 0x2a0e002a 0x55380055 0x7f7f007f 1983(0, 1) 0x2a000e2a 0x551c1c55 0x7f542a7f 0xaaaa38aa 1984(0, 2) 0x55003855 0x7f2a547f 0xaa7171aa 0xd4d48dd4 1985(0, 3) 0x7f007f7f 0xaa38aaaa 0xd48dd4d4 0xffffffff 1986Unpremultiplied: 1987(0, 0) 0x00000000 0x2a5500ff 0x55a800ff 0x7fff00ff 1988(0, 1) 0x2a0055ff 0x555454ff 0x7fa954ff 0xaaff54ff 1989(0, 2) 0x5500a8ff 0x7f54a9ff 0xaaaaaaff 0xd4ffaaff 1990(0, 3) 0x7f00ffff 0xaa54ffff 0xd4aaffff 0xffffffff 1991## 1992## 1993 1994#SeeAlso getAlphaf getAddr readPixels 1995 1996## 1997 1998#Method float getAlphaf(int x, int y) const 1999#In Property 2000#Line # returns Alpha normalized from zero to one ## 2001 2002Looks up the pixel at (x,y) and return its alpha component, normalized to [0..1]. 2003This is roughly equivalent to #Formula # SkGetColorA(getColor()) ##, but can be more efficient 2004(and more precise if the pixels store more than 8 bits per component). 2005 2006#Param x column index, zero or greater, and less than width() ## 2007#Param y row index, zero or greater, and less than height() ## 2008 2009#Return alpha converted to normalized float ## 2010 2011#NoExample 2012## 2013 2014#SeeAlso getColor 2015 2016## 2017 2018 2019# ------------------------------------------------------------------------------ 2020 2021#Method void* getAddr(int x, int y) const 2022#In Property 2023#Line # returns readable pixel address as void pointer ## 2024#Populate 2025 2026#Example 2027#Image 3 2028 char* row0 = (char* ) source.getAddr(0, 0); 2029 char* row1 = (char* ) source.getAddr(0, 1); 2030 SkDebugf("addr interval %c= rowBytes\n", 2031 (size_t) (row1 - row0) == source.rowBytes() ? '=' : '!'); 2032#StdOut 2033addr interval == rowBytes 2034## 2035## 2036 2037#SeeAlso getAddr8 getAddr16 getAddr32 readPixels SkPixmap::addr 2038 2039## 2040 2041# ------------------------------------------------------------------------------ 2042 2043#Method uint32_t* getAddr32(int x, int y) const 2044#In Property 2045#Line # returns readable pixel address as 32-bit pointer ## 2046Returns address at (x, y). 2047 2048Input is not validated. Triggers an assert() if built with SK_DEBUG defined and: 2049#List 2050# Pixel_Ref is nullptr ## 2051# bytesPerPixel() is not four ## 2052# x is negative, or not less than width() ## 2053# y is negative, or not less than height() ## 2054## 2055 2056#Param x column index, zero or greater, and less than width() ## 2057#Param y row index, zero or greater, and less than height() ## 2058 2059#Return unsigned 32-bit pointer to pixel at (x, y) ## 2060 2061#Example 2062#Image 3 2063 uint32_t* row0 = source.getAddr32(0, 0); 2064 uint32_t* row1 = source.getAddr32(0, 1); 2065 size_t interval = (row1 - row0) * source.bytesPerPixel(); 2066 SkDebugf("addr interval %c= rowBytes\n", interval == source.rowBytes() ? '=' : '!'); 2067#StdOut 2068addr interval == rowBytes 2069## 2070## 2071 2072#SeeAlso getAddr8 getAddr16 getAddr readPixels SkPixmap::addr32 2073 2074## 2075 2076# ------------------------------------------------------------------------------ 2077 2078#Method uint16_t* getAddr16(int x, int y) const 2079#In Property 2080#Line # returns readable pixel address as 16-bit pointer ## 2081Returns address at (x, y). 2082 2083Input is not validated. Triggers an assert() if built with SK_DEBUG defined and: 2084#List 2085# Pixel_Ref is nullptr ## 2086# bytesPerPixel() is not two ## 2087# x is negative, or not less than width() ## 2088# y is negative, or not less than height() ## 2089## 2090 2091#Param x column index, zero or greater, and less than width() ## 2092#Param y row index, zero or greater, and less than height() ## 2093 2094#Return unsigned 16-bit pointer to pixel at (x, y)## 2095 2096#Example 2097#Image 3 2098 SkBitmap bitmap16; 2099 SkImageInfo dstInfo = SkImageInfo::Make(source.width(), source.height(), kARGB_4444_SkColorType, 2100 kPremul_SkAlphaType); 2101 bitmap16.allocPixels(dstInfo); 2102 if (source.readPixels(dstInfo, bitmap16.getPixels(), bitmap16.rowBytes(), 0, 0)) { 2103 uint16_t* row0 = bitmap16.getAddr16(0, 0); 2104 uint16_t* row1 = bitmap16.getAddr16(0, 1); 2105 size_t interval = (row1 - row0) * bitmap16.bytesPerPixel(); 2106 SkDebugf("addr interval %c= rowBytes\n", interval == bitmap16.rowBytes() ? '=' : '!'); 2107 } 2108#StdOut 2109addr interval == rowBytes 2110## 2111## 2112 2113#SeeAlso getAddr8 getAddr getAddr32 readPixels SkPixmap::addr16 2114 2115## 2116 2117# ------------------------------------------------------------------------------ 2118 2119#Method uint8_t* getAddr8(int x, int y) const 2120#In Property 2121#Line # returns readable pixel address as 8-bit pointer ## 2122Returns address at (x, y). 2123 2124Input is not validated. Triggers an assert() if built with SK_DEBUG defined and: 2125#List 2126# Pixel_Ref is nullptr ## 2127# bytesPerPixel() is not one ## 2128# x is negative, or not less than width() ## 2129# y is negative, or not less than height() ## 2130## 2131 2132#Param x column index, zero or greater, and less than width() ## 2133#Param y row index, zero or greater, and less than height() ## 2134 2135#Return unsigned 8-bit pointer to pixel at (x, y) ## 2136 2137#Example 2138 SkBitmap bitmap; 2139 const int width = 8; 2140 const int height = 8; 2141 uint8_t pixels[height][width]; 2142 SkImageInfo info = SkImageInfo::Make(width, height, kGray_8_SkColorType, kOpaque_SkAlphaType); 2143 if (bitmap.installPixels(info, pixels, info.minRowBytes())) { 2144 SkDebugf("&pixels[4][2] %c= bitmap.getAddr8(2, 4)\n", 2145 &pixels[4][2] == bitmap.getAddr8(2, 4) ? '=' : '!'); 2146 } 2147#StdOut 2148&pixels[4][2] == bitmap.getAddr8(2, 4) 2149## 2150## 2151 2152#SeeAlso getAddr getAddr16 getAddr32 readPixels SkPixmap::addr8 2153 2154## 2155 2156# ------------------------------------------------------------------------------ 2157 2158#Method bool extractSubset(SkBitmap* dst, const SkIRect& subset) const 2159#In Constructors 2160#Line # creates Bitmap, sharing pixels if possible ## 2161Shares Pixel_Ref with dst. Pixels are not copied; Bitmap and dst point 2162to the same pixels; dst bounds() are set to the intersection of subset 2163and the original bounds(). 2164 2165subset may be larger than bounds(). Any area outside of bounds() is ignored. 2166 2167Any contents of dst are discarded. isVolatile setting is copied to dst. 2168dst is set to colorType, alphaType, and colorSpace. 2169 2170Return false if: 2171#List 2172# dst is nullptr ## 2173# Pixel_Ref is nullptr ## 2174# subset does not intersect bounds() ## 2175## 2176 2177#Param dst Bitmap set to subset ## 2178#Param subset rectangle of pixels to reference ## 2179 2180#Return true if dst is replaced by subset 2181## 2182 2183#Example 2184#Image 3 2185 SkIRect bounds, s; 2186 source.getBounds(&bounds); 2187 SkDebugf("bounds: %d, %d, %d, %d\n", bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom); 2188 SkBitmap subset; 2189 for (int left: { -100, 0, 100, 1000 } ) { 2190 for (int right: { 0, 100, 1000 } ) { 2191 SkIRect b = SkIRect::MakeLTRB(left, 100, right, 200); 2192 bool success = source.extractSubset(&subset, b); 2193 SkDebugf("subset: %4d, %4d, %4d, %4d ", b.fLeft, b.fTop, b.fRight, b.fBottom); 2194 SkDebugf("success; %s", success ? "true" : "false"); 2195 if (success) { 2196 subset.getBounds(&s); 2197 SkDebugf(" subset: %d, %d, %d, %d", s.fLeft, s.fTop, s.fRight, s.fBottom); 2198 } 2199 SkDebugf("\n"); 2200 } 2201 } 2202#StdOut 2203bounds: 0, 0, 512, 512 2204subset: -100, 100, 0, 200 success; false 2205subset: -100, 100, 100, 200 success; true subset: 0, 0, 100, 100 2206subset: -100, 100, 1000, 200 success; true subset: 0, 0, 512, 100 2207subset: 0, 100, 0, 200 success; false 2208subset: 0, 100, 100, 200 success; true subset: 0, 0, 100, 100 2209subset: 0, 100, 1000, 200 success; true subset: 0, 0, 512, 100 2210subset: 100, 100, 0, 200 success; false 2211subset: 100, 100, 100, 200 success; false 2212subset: 100, 100, 1000, 200 success; true subset: 0, 0, 412, 100 2213subset: 1000, 100, 0, 200 success; false 2214subset: 1000, 100, 100, 200 success; false 2215subset: 1000, 100, 1000, 200 success; false 2216## 2217## 2218 2219#SeeAlso readPixels writePixels SkCanvas::drawBitmap 2220 2221## 2222 2223# ------------------------------------------------------------------------------ 2224 2225#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, 2226 int srcX, int srcY) const 2227#In Pixels 2228#Line # copies and converts pixels ## 2229 2230Copies a Rect of pixels from Bitmap to dstPixels. Copy starts at (srcX, srcY), 2231and does not exceed Bitmap (width(), height()). 2232 2233dstInfo specifies width, height, Color_Type, Alpha_Type, and Color_Space of 2234destination. dstRowBytes specifics the gap from one destination row to the next. 2235Returns true if pixels are copied. Returns false if: 2236#List 2237# dstInfo has no address ## 2238# dstRowBytes is less than dstInfo.minRowBytes() ## 2239# Pixel_Ref is nullptr ## 2240## 2241 2242Pixels are copied only if pixel conversion is possible. If Bitmap colorType is 2243kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType() must match. 2244If Bitmap colorType is kGray_8_SkColorType, dstInfo.colorSpace() must match. 2245If Bitmap alphaType is kOpaque_SkAlphaType, dstInfo.alphaType() must 2246match. If Bitmap colorSpace is nullptr, dstInfo.colorSpace() must match. Returns 2247false if pixel conversion is not possible. 2248 2249srcX and srcY may be negative to copy only top or left of source. Returns 2250false if width() or height() is zero or negative. 2251Returns false if #Formula # abs(srcX) >= Bitmap width() ##, or if #Formula # abs(srcY) >= Bitmap height() ##. 2252 2253#Param dstInfo destination width, height, Color_Type, Alpha_Type, Color_Space ## 2254#Param dstPixels destination pixel storage ## 2255#Param dstRowBytes destination row length ## 2256#Param srcX column index whose absolute value is less than width() ## 2257#Param srcY row index whose absolute value is less than height() ## 2258 2259#Return true if pixels are copied to dstPixels ## 2260 2261#Example 2262#Height 128 2263#Description 2264Transferring the gradient from 8 bits per component to 4 bits per component 2265creates visible banding. 2266## 2267 const int width = 256; 2268 const int height = 64; 2269 SkImageInfo srcInfo = SkImageInfo::MakeN32Premul(width, height); 2270 SkColor gradColors[] = { 0xFFAA3300, 0x7F881122 }; 2271 SkPoint gradPoints[] = { { 0, 0 }, { 256, 0 } }; 2272 SkPaint paint; 2273 paint.setShader(SkGradientShader::MakeLinear(gradPoints, gradColors, nullptr, 2274 SK_ARRAY_COUNT(gradColors), SkShader::kClamp_TileMode)); 2275 SkBitmap bitmap; 2276 bitmap.allocPixels(srcInfo); 2277 SkCanvas srcCanvas(bitmap); 2278 srcCanvas.drawRect(SkRect::MakeWH(width, height), paint); 2279 canvas->drawBitmap(bitmap, 0, 0); 2280 SkImageInfo dstInfo = srcInfo.makeColorType(kARGB_4444_SkColorType); 2281 std::vector<int16_t> dstPixels; 2282 dstPixels.resize(height * width); 2283 bitmap.readPixels(dstInfo, &dstPixels.front(), width * 2, 0, 0); 2284 SkPixmap dstPixmap(dstInfo, &dstPixels.front(), width * 2); 2285 bitmap.installPixels(dstPixmap); 2286 canvas->drawBitmap(bitmap, 0, 64); 2287## 2288 2289#SeeAlso writePixels SkPixmap::readPixels SkCanvas::readPixels SkImage::readPixels SkSurface::readPixels 2290 2291## 2292 2293# ------------------------------------------------------------------------------ 2294 2295#Method bool readPixels(const SkPixmap& dst, int srcX, int srcY) const 2296 2297Copies a Rect of pixels from Bitmap to dst. Copy starts at (srcX, srcY), and 2298does not exceed Bitmap (width(), height()). 2299 2300dst specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage, 2301and row bytes of destination. dst.rowBytes() specifics the gap from one destination 2302row to the next. Returns true if pixels are copied. Returns false if: 2303#List 2304# dst pixel storage equals nullptr ## 2305# dst.rowBytes() is less than SkImageInfo::minRowBytes() ## 2306# Pixel_Ref is nullptr ## 2307## 2308 2309Pixels are copied only if pixel conversion is possible. If Bitmap colorType is 2310kGray_8_SkColorType, or kAlpha_8_SkColorType; dst Color_Type must match. 2311If Bitmap colorType is kGray_8_SkColorType, dst Color_Space must match. 2312If Bitmap alphaType is kOpaque_SkAlphaType, dst Alpha_Type must 2313match. If Bitmap colorSpace is nullptr, dst Color_Space must match. Returns 2314false if pixel conversion is not possible. 2315 2316srcX and srcY may be negative to copy only top or left of source. Returns 2317false if width() or height() is zero or negative. 2318Returns false if #Formula # abs(srcX) >= Bitmap width() ##, or if #Formula # abs(srcY) >= Bitmap height() ##. 2319 2320#Param dst destination Pixmap: Image_Info, pixels, row bytes ## 2321#Param srcX column index whose absolute value is less than width() ## 2322#Param srcY row index whose absolute value is less than height() ## 2323 2324#Return true if pixels are copied to dst ## 2325 2326#Example 2327#Image 3 2328 std::vector<int32_t> srcPixels; 2329 srcPixels.resize(source.height() * source.rowBytes()); 2330 for (int y = 0; y < 4; ++y) { 2331 for (int x = 0; x < 4; ++x) { 2332 SkPixmap pixmap(SkImageInfo::MakeN32Premul(source.width() / 4, source.height() / 4), 2333 &srcPixels.front() + x * source.height() * source.width() / 4 + 2334 y * source.width() / 4, source.rowBytes()); 2335 source.readPixels(pixmap, x * source.width() / 4, y * source.height() / 4); 2336 } 2337 } 2338 canvas->scale(.5f, .5f); 2339 SkBitmap bitmap; 2340 bitmap.installPixels(SkImageInfo::MakeN32Premul(source.width(), source.height()), 2341 &srcPixels.front(), source.rowBytes()); 2342 canvas->drawBitmap(bitmap, 0, 0); 2343## 2344 2345#SeeAlso writePixels SkPixmap::readPixels SkCanvas::readPixels SkImage::readPixels SkSurface::readPixels 2346 2347## 2348 2349# ------------------------------------------------------------------------------ 2350 2351#Method bool readPixels(const SkPixmap& dst) const 2352 2353Copies a Rect of pixels from Bitmap to dst. Copy starts at (0, 0), and 2354does not exceed Bitmap (width(), height()). 2355 2356dst specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage, 2357and row bytes of destination. dst.rowBytes() specifics the gap from one destination 2358row to the next. Returns true if pixels are copied. Returns false if: 2359#List 2360# dst pixel storage equals nullptr ## 2361# dst.rowBytes() is less than SkImageInfo::minRowBytes() ## 2362# Pixel_Ref is nullptr ## 2363## 2364 2365Pixels are copied only if pixel conversion is possible. If Bitmap colorType is 2366kGray_8_SkColorType, or kAlpha_8_SkColorType; dst Color_Type must match. 2367If Bitmap colorType is kGray_8_SkColorType, dst Color_Space must match. 2368If Bitmap alphaType is kOpaque_SkAlphaType, dst Alpha_Type must 2369match. If Bitmap colorSpace is nullptr, dst Color_Space must match. Returns 2370false if pixel conversion is not possible. 2371 2372#Param dst destination Pixmap: Image_Info, pixels, row bytes ## 2373 2374#Return true if pixels are copied to dst ## 2375 2376#Example 2377#Height 128 2378#Image 3 2379 std::vector<int32_t> srcPixels; 2380 srcPixels.resize(source.height() * source.width() * 8); 2381 for (int i = 0; i < 2; ++i) { 2382 SkPixmap pixmap(SkImageInfo::Make(source.width() * 2, source.height(), 2383 i ? kRGBA_8888_SkColorType : kBGRA_8888_SkColorType, kPremul_SkAlphaType), 2384 &srcPixels.front() + i * source.width(), source.rowBytes() * 2); 2385 source.readPixels(pixmap); 2386 } 2387 canvas->scale(.25f, .25f); 2388 SkBitmap bitmap; 2389 bitmap.installPixels(SkImageInfo::MakeN32Premul(source.width() * 2, source.height()), 2390 &srcPixels.front(), source.rowBytes() * 2); 2391 canvas->drawBitmap(bitmap, 0, 0); 2392## 2393 2394#SeeAlso writePixels SkPixmap::readPixels SkCanvas::readPixels SkImage::readPixels SkSurface::readPixels 2395 2396## 2397 2398# ------------------------------------------------------------------------------ 2399 2400#Method bool writePixels(const SkPixmap& src, int dstX, int dstY) 2401#In Pixels 2402#Line # copies and converts pixels ## 2403Copies a Rect of pixels from src. Copy starts at (dstX, dstY), and does not exceed 2404(src.width(), src.height()). 2405 2406src specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage, 2407and row bytes of source. src.rowBytes() specifics the gap from one source 2408row to the next. Returns true if pixels are copied. Returns false if: 2409#List 2410# src pixel storage equals nullptr ## 2411# src.rowBytes() is less than SkImageInfo::minRowBytes() ## 2412# Pixel_Ref is nullptr ## 2413## 2414 2415Pixels are copied only if pixel conversion is possible. If Bitmap colorType is 2416kGray_8_SkColorType, or kAlpha_8_SkColorType; src Color_Type must match. 2417If Bitmap colorType is kGray_8_SkColorType, src Color_Space must match. 2418If Bitmap alphaType is kOpaque_SkAlphaType, src Alpha_Type must 2419match. If Bitmap colorSpace is nullptr, src Color_Space must match. Returns 2420false if pixel conversion is not possible. 2421 2422dstX and dstY may be negative to copy only top or left of source. Returns 2423false if width() or height() is zero or negative. 2424Returns false if #Formula # abs(dstX) >= Bitmap width() ##, or if #Formula # abs(dstY) >= Bitmap height() ##. 2425 2426#Param src source Pixmap: Image_Info, pixels, row bytes ## 2427#Param dstX column index whose absolute value is less than width() ## 2428#Param dstY row index whose absolute value is less than height() ## 2429 2430#Return true if src pixels are copied to Bitmap ## 2431 2432#Example 2433#Image 3 2434 std::vector<int32_t> srcPixels; 2435 int width = image->width(); 2436 int height = image->height(); 2437 srcPixels.resize(height * width * 4); 2438 SkPixmap pixmap(SkImageInfo::MakeN32Premul(width, height), (const void*) &srcPixels.front(), 2439 width * 4); 2440 image->readPixels(pixmap, 0, 0); 2441 canvas->scale(.5f, .5f); 2442 width /= 4; 2443 height /= 4; 2444 for (int y = 0; y < 4; ++y) { 2445 for (int x = 0; x < 4; ++x) { 2446 SkBitmap bitmap; 2447 bitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height)); 2448 bitmap.writePixels(pixmap, -y * width, -x * height); 2449 canvas->drawBitmap(bitmap, x * width, y * height); 2450 } 2451 } 2452## 2453 2454#SeeAlso readPixels 2455 2456## 2457 2458# ------------------------------------------------------------------------------ 2459 2460#Method bool writePixels(const SkPixmap& src) 2461 2462Copies a Rect of pixels from src. Copy starts at (0, 0), and does not exceed 2463(src.width(), src.height()). 2464 2465src specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage, 2466and row bytes of source. src.rowBytes() specifics the gap from one source 2467row to the next. Returns true if pixels are copied. Returns false if: 2468#List 2469# src pixel storage equals nullptr ## 2470# src.rowBytes() is less than SkImageInfo::minRowBytes() ## 2471# Pixel_Ref is nullptr ## 2472## 2473 2474Pixels are copied only if pixel conversion is possible. If Bitmap colorType is 2475kGray_8_SkColorType, or kAlpha_8_SkColorType; src Color_Type must match. 2476If Bitmap colorType is kGray_8_SkColorType, src Color_Space must match. 2477If Bitmap alphaType is kOpaque_SkAlphaType, src Alpha_Type must 2478match. If Bitmap colorSpace is nullptr, src Color_Space must match. Returns 2479false if pixel conversion is not possible. 2480 2481#Param src source Pixmap: Image_Info, pixels, row bytes ## 2482 2483#Return true if src pixels are copied to Bitmap ## 2484 2485#Example 2486#Height 80 2487 SkBitmap bitmap; 2488 bitmap.allocPixels(SkImageInfo::MakeN32Premul(2, 2)); 2489 bitmap.eraseColor(SK_ColorGREEN); 2490 SkPMColor color = 0xFF5599BB; 2491 SkPixmap src(SkImageInfo::MakeN32Premul(1, 1), &color, 4); 2492 bitmap.writePixels(src); 2493 canvas->scale(40, 40); 2494 canvas->drawBitmap(bitmap, 0, 0); 2495## 2496 2497#SeeAlso readPixels 2498 2499## 2500 2501# ------------------------------------------------------------------------------ 2502 2503#Method bool extractAlpha(SkBitmap* dst) const 2504#In Constructors 2505#Line # creates Bitmap containing Alpha of pixels ## 2506#Populate 2507 2508#Example 2509#Height 100 2510 SkBitmap alpha, bitmap; 2511 bitmap.allocN32Pixels(100, 100); 2512 SkCanvas offscreen(bitmap); 2513 offscreen.clear(0); 2514 SkPaint paint; 2515 paint.setAntiAlias(true); 2516 paint.setColor(SK_ColorBLUE); 2517 paint.setStyle(SkPaint::kStroke_Style); 2518 paint.setStrokeWidth(20); 2519 offscreen.drawCircle(50, 50, 39, paint); 2520 offscreen.flush(); 2521 bitmap.extractAlpha(&alpha); 2522 paint.setColor(SK_ColorRED); 2523 canvas->drawBitmap(bitmap, 0, 0, &paint); 2524 canvas->drawBitmap(alpha, 100, 0, &paint); 2525## 2526 2527#SeeAlso extractSubset 2528 2529## 2530 2531# ------------------------------------------------------------------------------ 2532 2533#Method bool extractAlpha(SkBitmap* dst, const SkPaint* paint, 2534 SkIPoint* offset) const 2535#Populate 2536 2537#Example 2538#Height 160 2539 auto radiusToSigma = [](SkScalar radius) -> SkScalar { 2540 static const SkScalar kBLUR_SIGMA_SCALE = 0.57735f; 2541 return radius > 0 ? kBLUR_SIGMA_SCALE * radius + 0.5f : 0.0f; 2542 }; 2543 SkBitmap alpha, bitmap; 2544 bitmap.allocN32Pixels(100, 100); 2545 SkCanvas offscreen(bitmap); 2546 offscreen.clear(0); 2547 SkPaint paint; 2548 paint.setAntiAlias(true); 2549 paint.setColor(SK_ColorBLUE); 2550 paint.setStyle(SkPaint::kStroke_Style); 2551 paint.setStrokeWidth(20); 2552 offscreen.drawCircle(50, 50, 39, paint); 2553 offscreen.flush(); 2554 paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, radiusToSigma(25))); 2555 SkIPoint offset; 2556 bitmap.extractAlpha(&alpha, &paint, &offset); 2557 paint.setColor(SK_ColorRED); 2558 canvas->drawBitmap(bitmap, 0, -offset.fY, &paint); 2559 canvas->drawBitmap(alpha, 100 + offset.fX, 0, &paint); 2560## 2561 2562#SeeAlso extractSubset 2563 2564## 2565 2566# ------------------------------------------------------------------------------ 2567 2568#Method bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator, 2569 SkIPoint* offset) const 2570#Populate 2571 2572#Example 2573#Height 128 2574 SkBitmap alpha, bitmap; 2575 bitmap.allocN32Pixels(100, 100); 2576 SkCanvas offscreen(bitmap); 2577 offscreen.clear(0); 2578 SkPaint paint; 2579 paint.setAntiAlias(true); 2580 paint.setColor(SK_ColorBLUE); 2581 paint.setStyle(SkPaint::kStroke_Style); 2582 paint.setStrokeWidth(20); 2583 offscreen.drawCircle(50, 50, 39, paint); 2584 offscreen.flush(); 2585 paint.setMaskFilter(SkMaskFilter::MakeBlur(kOuter_SkBlurStyle, 3)); 2586 SkIPoint offset; 2587 bitmap.extractAlpha(&alpha, &paint, nullptr, &offset); 2588 paint.setColor(SK_ColorRED); 2589 canvas->drawBitmap(bitmap, 0, -offset.fY, &paint); 2590 canvas->drawBitmap(alpha, 100 + offset.fX, 0, &paint); 2591## 2592 2593#SeeAlso extractSubset 2594 2595## 2596 2597# ------------------------------------------------------------------------------ 2598 2599#Method bool peekPixels(SkPixmap* pixmap) const 2600#In Pixels 2601#Line # returns Pixmap if possible ## 2602#Populate 2603 2604#Example 2605 SkBitmap bitmap; 2606 bitmap.allocPixels(SkImageInfo::MakeN32Premul(6, 11)); 2607 SkCanvas offscreen(bitmap); 2608 offscreen.clear(SK_ColorWHITE); 2609 SkPaint paint; 2610 offscreen.drawString("?", 0, 10, paint); 2611 SkPixmap pixmap; 2612 if (bitmap.peekPixels(&pixmap)) { 2613 const SkPMColor* pixels = pixmap.addr32(); 2614 SkPMColor pmWhite = pixels[0]; 2615 for (int y = 0; y < bitmap.height(); ++y) { 2616 for (int x = 0; x < bitmap.width(); ++x) { 2617 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x'); 2618 } 2619 SkDebugf("\n"); 2620 } 2621 } 2622 #StdOut 2623------ 2624-xxx-- 2625x---x- 2626----x- 2627---x-- 2628--x--- 2629--x--- 2630------ 2631--x--- 2632--x--- 2633------ 2634 #StdOut ## 2635## 2636 2637#SeeAlso pixmap installPixels readPixels writePixels 2638 2639## 2640 2641# ------------------------------------------------------------------------------ 2642#Subtopic Utility 2643#Line # rarely called management functions ## 2644## 2645 2646#Method void validate() const; 2647#In Utility 2648#Line # asserts if Bitmap is invalid (debug only) ## 2649#Populate 2650 2651#NoExample 2652## 2653 2654#SeeAlso SkImageInfo::validate 2655 2656## 2657 2658# ------------------------------------------------------------------------------ 2659 2660#Class SkBitmap ## 2661 2662#Topic Bitmap ## 2663