#Topic Bitmap #Alias Bitmaps #Alias Bitmap_Reference #Subtopic Overview #Subtopic Subtopics #Populate ## ## #Class SkBitmap Bitmap describes a two-dimensional raster pixel array. Bitmap is built on Image_Info, containing integer width and height, Color_Type and Alpha_Type describing the pixel format, and Color_Space describing the range of colors. Bitmap points to Pixel_Ref, which describes the physical array of pixels. Image_Info bounds may be located anywhere fully inside Pixel_Ref bounds. Bitmap can be drawn using Canvas. Bitmap can be a drawing destination for Canvas draw methods. Bitmap flexibility as a pixel container limits some optimizations available to the target platform. If pixel array is primarily read-only, use Image for better performance. If pixel array is primarily written to, use Surface for better performance. Declaring SkBitmap const prevents altering Image_Info: the Bitmap height, width, and so on cannot change. It does not affect Pixel_Ref: a caller may write its pixels. Declaring SkBitmap const affects Bitmap configuration, not its contents. Bitmap is not thread safe. Each thread must have its own copy of Bitmap fields, although threads may share the underlying pixel array. #Subtopic Row_Bytes #Line # interval from one row to the next ## Bitmap pixels may be contiguous, or may have a gap at the end of each row. Row_Bytes is the interval from one row to the next. Row_Bytes may be specified; sometimes passing zero will compute the Row_Bytes from the row width and the number of bytes in a pixel. Row_Bytes may be larger than the row requires. This is useful to position one or more Bitmaps within a shared pixel array. ## #Subtopic Related_Functions #Populate ## #Subtopic Classes_and_Structs #Populate ## #Subtopic Constructors #Populate ## #Subtopic Operators #Populate ## #Subtopic Member_Functions #Populate ## # ------------------------------------------------------------------------------ #Class Allocator #Line # abstract subclass of HeapAllocator ## #Code class Allocator : public SkRefCnt { public: virtual bool allocPixelRef(SkBitmap* bitmap) = 0; }; ## Abstract subclass of HeapAllocator. # ------------------------------------------------------------------------------ #Method virtual bool allocPixelRef(SkBitmap* bitmap) = 0 Allocates the pixel memory for the bitmap, given its dimensions and Color_Type. Returns true on success, where success means either setPixels or setPixelRef was called. #Param bitmap Bitmap containing Image_Info as input, and Pixel_Ref as output ## #Return true if Pixel_Ref was allocated ## #NoExample ## #SeeAlso HeapAllocator ## #Class Allocator ## # ------------------------------------------------------------------------------ #Class HeapAllocator #Line # allocates pixel memory from heap ## #Code class HeapAllocator : public Allocator { public: bool allocPixelRef(SkBitmap* bitmap) override; }; ## Subclass of Allocator that returns a Pixel_Ref that allocates its pixel memory from the heap. This is the default Allocator invoked by allocPixels. # ------------------------------------------------------------------------------ #Method bool allocPixelRef(SkBitmap* bitmap) override Allocates the pixel memory for the bitmap, given its dimensions and Color_Type. Returns true on success, where success means either setPixels or setPixelRef was called. #Param bitmap Bitmap containing Image_Info as input, and Pixel_Ref as output ## #Return true if pixels are allocated ## #Example SkBitmap bitmap; bitmap.setInfo(SkImageInfo::MakeN32(16, 16, kPremul_SkAlphaType)); SkDebugf("pixel address = %p\n", bitmap.getPixels()); SkBitmap::HeapAllocator stdalloc; if (!stdalloc.allocPixelRef(&bitmap)) { SkDebugf("pixel allocation failed\n"); } else { SkDebugf("pixel address = %p\n", bitmap.getPixels()); } #StdOut #Volatile pixel address = (nil) pixel address = 0x560ddd0ac670 ## ## #SeeAlso Allocator tryAllocPixels ## #Class HeapAllocator ## # ------------------------------------------------------------------------------ #Method SkBitmap() #Line # constructs with default values ## Creates an empty Bitmap without pixels, with kUnknown_SkColorType, kUnknown_SkAlphaType, and with a width and height of zero. Pixel_Ref origin is set to (0, 0). Bitmap is not volatile. Use setInfo to associate SkColorType, SkAlphaType, width, and height after Bitmap has been created. #Return empty Bitmap ## #Example void draw(SkCanvas* canvas) { const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"}; const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x", "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"}; SkBitmap bitmap; for (int i = 0; i < 2; ++i) { SkDebugf("width: %2d height: %2d", bitmap.width(), bitmap.height()); SkDebugf(" color: k%s_SkColorType", colors[bitmap.colorType()]); SkDebugf(" alpha: k%s_SkAlphaType\n", alphas[bitmap.alphaType()]); bitmap.setInfo(SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType), 0); } } #StdOut width: 0 height: 0 color: kUnknown_SkColorType alpha: kUnknown_SkAlphaType width: 25 height: 35 color: kRGBA_8888_SkColorType alpha: kOpaque_SkAlphaType ## ## #SeeAlso setInfo ## # ------------------------------------------------------------------------------ #Method SkBitmap(const SkBitmap& src) #Line # shares ownership of pixels ## Copies settings from src to returned Bitmap. Shares pixels if src has pixels allocated, so both bitmaps reference the same pixels. #Param src Bitmap to copy Image_Info, and share Pixel_Ref ## #Return copy of src ## #Example void draw(SkCanvas* canvas) { SkBitmap original; original.tryAllocPixels(SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType)); SkDebugf("original has pixels before copy: %s\n", original.getPixels() ? "true" : "false"); SkBitmap copy(original); SkDebugf("original has pixels after copy: %s\n", original.getPixels() ? "true" : "false"); SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false"); } #StdOut original has pixels before copy: true original has pixels after copy: true copy has pixels: true ## ## #SeeAlso setInfo setPixelRef setPixels swap ## # ------------------------------------------------------------------------------ #Method SkBitmap(SkBitmap&& src) #Line # takes ownership of pixels ## Copies settings from src to returned Bitmap. Moves ownership of src pixels to Bitmap. #Param src Bitmap to copy Image_Info, and reassign Pixel_Ref ## #Return copy of src ## #Example void draw(SkCanvas* canvas) { SkBitmap original; original.tryAllocPixels(SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType)); SkDebugf("original has pixels before move: %s\n", original.getPixels() ? "true" : "false"); SkBitmap copy(std::move(original)); SkDebugf("original has pixels after move: %s\n", original.getPixels() ? "true" : "false"); SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false"); } #StdOut original has pixels before move: true original has pixels after move: false copy has pixels: true ## ## #SeeAlso setInfo setPixelRef setPixels swap ## # ------------------------------------------------------------------------------ #Method ~SkBitmap() #Line # releases ownership of pixels ## Decrements Pixel_Ref reference count, if Pixel_Ref is not nullptr. #NoExample ## #SeeAlso Pixel_Ref ## # ------------------------------------------------------------------------------ #Method SkBitmap& operator=(const SkBitmap& src) #Line # shares ownership of pixels ## Copies settings from src to returned Bitmap. Shares pixels if src has pixels allocated, so both bitmaps reference the same pixels. #Param src Bitmap to copy Image_Info, and share Pixel_Ref ## #Return copy of src ## #Example void draw(SkCanvas* canvas) { SkBitmap original; original.tryAllocPixels(SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType)); SkDebugf("original has pixels before copy: %s\n", original.getPixels() ? "true" : "false"); SkBitmap copy = original; SkDebugf("original has pixels after copy: %s\n", original.getPixels() ? "true" : "false"); SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false"); } #StdOut original has pixels before copy: true original has pixels after copy: true copy has pixels: true ## ## #SeeAlso setInfo setPixelRef setPixels swap ## # ------------------------------------------------------------------------------ #Method SkBitmap& operator=(SkBitmap&& src) #Line # takes ownership of pixels ## Copies settings from src to returned Bitmap. Moves ownership of src pixels to Bitmap. #Param src Bitmap to copy Image_Info, and reassign Pixel_Ref ## #Return copy of src ## #Example void draw(SkCanvas* canvas) { SkBitmap original; original.tryAllocPixels(SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType)); SkDebugf("original has pixels before move: %s\n", original.getPixels() ? "true" : "false"); SkBitmap copy = std::move(original); SkDebugf("original has pixels after move: %s\n", original.getPixels() ? "true" : "false"); SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false"); } #StdOut original has pixels before move: true original has pixels after move: false copy has pixels: true ## ## #SeeAlso setInfo setPixelRef setPixels swap ## # ------------------------------------------------------------------------------ #Method void swap(SkBitmap& other) #Line # exchanges Bitmap pair ## Swaps the fields of the two bitmaps. #Param other Bitmap exchanged with original ## #Example void draw(SkCanvas* canvas) { auto debugster = [](const char* prefix, const SkBitmap& b) -> void { const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"}; const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x", "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"}; SkDebugf("%s width:%d height:%d colorType:k%s_SkColorType alphaType:k%s_SkAlphaType\n", prefix, b.width(), b.height(), colors[b.colorType()], alphas[b.alphaType()]); }; SkBitmap one, two; one.tryAllocPixels(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType)); two.tryAllocPixels(SkImageInfo::Make(2, 2, kBGRA_8888_SkColorType, kPremul_SkAlphaType)); for (int index = 0; index < 2; ++index) { debugster("one", one); debugster("two", two); one.swap(two); } } #StdOut one width:1 height:1 colorType:kRGBA_8888_SkColorType alphaType:kOpaque_SkAlphaType two width:2 height:2 colorType:kBGRA_8888_SkColorType alphaType:kPremul_SkAlphaType one width:2 height:2 colorType:kBGRA_8888_SkColorType alphaType:kPremul_SkAlphaType two width:1 height:1 colorType:kRGBA_8888_SkColorType alphaType:kOpaque_SkAlphaType ## ## #SeeAlso SkBitmap(SkBitmap&& src) operator=(SkBitmap&& src) ## # ------------------------------------------------------------------------------ #Method const SkPixmap& pixmap() const #Line # returns Pixmap ## Returns a constant reference to the Pixmap holding the Bitmap pixel address, row bytes, and Image_Info. #Return reference to Pixmap describing this Bitmap ## #Example SkBitmap bitmap; bitmap.allocPixels(SkImageInfo::MakeN32Premul(10, 11)); SkCanvas offscreen(bitmap); offscreen.clear(SK_ColorWHITE); SkPaint paint; offscreen.drawString("&", 0, 10, paint); const SkPixmap& pixmap = bitmap.pixmap(); if (pixmap.addr()) { SkPMColor pmWhite = *pixmap.addr32(0, 0); for (int y = 0; y < pixmap.height(); ++y) { for (int x = 0; x < pixmap.width(); ++x) { SkDebugf("%c", *pixmap.addr32(x, y) == pmWhite ? '-' : 'x'); } SkDebugf("\n"); } } #StdOut ---------- ---xx----- --x--x---- --x------- --xx------ --x-x---x- -x---x--x- -x----xx-- -xx---x--- --xxxx-xx- ---------- #StdOut ## ## #SeeAlso peekPixels installPixels readPixels writePixels ## # ------------------------------------------------------------------------------ #Method const SkImageInfo& info() const #Line # returns Image_Info ## Returns width, height, Alpha_Type, Color_Type, and Color_Space. #Return reference to Image_Info ## #Example #Image 4 void draw(SkCanvas* canvas) { // SkBitmap source; // pre-populated with soccer ball by fiddle.skia.org const SkImageInfo& info = source.info(); const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"}; const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x", "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"}; SkDebugf("width: %d height: %d color: %s alpha: %s\n", info.width(), info.height(), colors[info.colorType()], alphas[info.alphaType()]); #StdOut width: 56 height: 56 color: BGRA_8888 alpha: Opaque ## } ## #SeeAlso Image_Info ## # ------------------------------------------------------------------------------ #Method int width() const #Line # returns pixel column count ## Returns pixel count in each row. Should be equal or less than: #Formula rowBytes() / info().bytesPerPixel() ## . Maybe be less than pixelRef().width(). Will not exceed pixelRef().width() less pixelRefOrigin().fX. #Return pixel width in Image_Info ## #Example SkImageInfo info = SkImageInfo::MakeA8(16, 32); SkBitmap bitmap; bitmap.setInfo(info); SkDebugf("bitmap width: %d info width: %d\n", bitmap.width(), info.width()); #StdOut bitmap width: 16 info width: 16 ## ## #SeeAlso height() SkPixelRef::width() SkImageInfo::width() ## # ------------------------------------------------------------------------------ #Method int height() const #Line # returns pixel row count ## Returns pixel row count. Maybe be less than pixelRef().height(). Will not exceed pixelRef().height() less pixelRefOrigin().fY. #Return pixel height in Image_Info ## #Example SkImageInfo info = SkImageInfo::MakeA8(16, 32); SkBitmap bitmap; bitmap.setInfo(info); SkDebugf("bitmap height: %d info height: %d\n", bitmap.height(), info.height()); #StdOut bitmap height: 32 info height: 32 ## ## #SeeAlso width() SkPixelRef::height() SkImageInfo::height() ## # ------------------------------------------------------------------------------ #Method SkColorType colorType() const #Line # returns Image_Info Color_Type ## Returns Color_Type, one of: kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType, kARGB_4444_SkColorType, kRGBA_8888_SkColorType, kBGRA_8888_SkColorType, kGray_8_SkColorType, kRGBA_F16_SkColorType. #Return Color_Type in Image_Info ## #Example const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x", "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"}; SkBitmap bitmap; bitmap.setInfo(SkImageInfo::MakeA8(16, 32)); SkDebugf("color type: k" "%s" "_SkColorType\n", colors[bitmap.colorType()]); #StdOut color type: kAlpha_8_SkColorType ## ## #SeeAlso alphaType() SkImageInfo::colorType ## # ------------------------------------------------------------------------------ #Method SkAlphaType alphaType() const #Line # returns Image_Info Alpha_Type ## Returns Alpha_Type, one of: kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType, kUnpremul_SkAlphaType. #Return Alpha_Type in Image_Info ## #Example const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"}; SkPixmap pixmap(SkImageInfo::MakeA8(16, 32), nullptr, 64); SkDebugf("alpha type: k" "%s" "_SkAlphaType\n", alphas[pixmap.alphaType()]); #StdOut alpha type: kPremul_SkAlphaType ## ## #SeeAlso colorType() SkImageInfo::alphaType ## # ------------------------------------------------------------------------------ #Method SkColorSpace* colorSpace() const #Line # returns Image_Info Color_Space ## Returns Color_Space, the range of colors, associated with Image_Info. The reference count of Color_Space is unchanged. The returned Color_Space is immutable. #Return Color_Space in Image_Info, or nullptr ## #Example #Description SkColorSpace::MakeSRGBLinear creates Color_Space with linear gamma and an sRGB gamut. This Color_Space gamma is not close to sRGB gamma. ## SkBitmap bitmap; bitmap.setInfo(SkImageInfo::MakeN32(16, 32, kPremul_SkAlphaType, SkColorSpace::MakeSRGBLinear())); SkColorSpace* colorSpace = bitmap.colorSpace(); SkDebugf("gammaCloseToSRGB: %s gammaIsLinear: %s isSRGB: %s\n", colorSpace->gammaCloseToSRGB() ? "true" : "false", colorSpace->gammaIsLinear() ? "true" : "false", colorSpace->isSRGB() ? "true" : "false"); #StdOut gammaCloseToSRGB: false gammaIsLinear: true isSRGB: false ## ## #SeeAlso Color_Space SkImageInfo::colorSpace ## # ------------------------------------------------------------------------------ #Method sk_sp<SkColorSpace> refColorSpace() const #Line # returns Image_Info Color_Space ## Returns a smart pointer to Color_Space, the range of colors, associated with Image_Info. The smart pointer tracks the number of objects sharing this Color_Space reference so the memory is released when the owners destruct. The returned Color_Space is immutable. #Return Color_Space in Image_Info wrapped in a smart pointer ## #Example SkBitmap bitmap1, bitmap2; bitmap1.setInfo(SkImageInfo::MakeN32(16, 32, kPremul_SkAlphaType, SkColorSpace::MakeSRGBLinear())); bitmap2.setInfo(SkImageInfo::MakeN32(16, 32, kPremul_SkAlphaType, bitmap1.refColorSpace())); SkColorSpace* colorSpace = bitmap2.colorSpace(); SkDebugf("gammaCloseToSRGB: %s gammaIsLinear: %s isSRGB: %s\n", colorSpace->gammaCloseToSRGB() ? "true" : "false", colorSpace->gammaIsLinear() ? "true" : "false", colorSpace->isSRGB() ? "true" : "false"); #StdOut gammaCloseToSRGB: false gammaIsLinear: true isSRGB: false ## ## #SeeAlso Color_Space SkImageInfo::colorSpace ## # ------------------------------------------------------------------------------ #Method int bytesPerPixel() const #Line # returns number of bytes in pixel based on Color_Type ## Returns number of bytes per pixel required by Color_Type. Returns zero if colorType( is kUnknown_SkColorType. #Return bytes in pixel ## #Example const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x", "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"}; SkImageInfo info = SkImageInfo::MakeA8(1, 1); SkBitmap bitmap; for (SkColorType colorType : { kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType, kARGB_4444_SkColorType, kRGBA_8888_SkColorType, kBGRA_8888_SkColorType, kGray_8_SkColorType, kRGBA_F16_SkColorType } ) { bitmap.setInfo(info.makeColorType(colorType)); SkDebugf("color: k" "%s" "_SkColorType" "%*s" "bytesPerPixel: %d\n", colors[colorType], 13 - strlen(colors[colorType]), " ", bitmap.bytesPerPixel()); } #StdOut color: kUnknown_SkColorType bytesPerPixel: 0 color: kAlpha_8_SkColorType bytesPerPixel: 1 color: kRGB_565_SkColorType bytesPerPixel: 2 color: kARGB_4444_SkColorType bytesPerPixel: 2 color: kRGBA_8888_SkColorType bytesPerPixel: 4 color: kBGRA_8888_SkColorType bytesPerPixel: 4 color: kGray_8_SkColorType bytesPerPixel: 1 color: kRGBA_F16_SkColorType bytesPerPixel: 8 ## ## #SeeAlso rowBytes rowBytesAsPixels width shiftPerPixel ## # ------------------------------------------------------------------------------ #Method int rowBytesAsPixels() const #Line # returns interval between rows in pixels ## Returns number of pixels that fit on row. Should be greater than or equal to width(). #Return maximum pixels per row ## #Example SkBitmap bitmap; for (int rowBytes : { 4, 5, 6, 7, 8} ) { bitmap.setInfo(SkImageInfo::MakeN32(1, 1, kPremul_SkAlphaType), rowBytes); SkDebugf("rowBytes: %d rowBytesAsPixels: %d\n", rowBytes, bitmap.rowBytesAsPixels()); } #StdOut rowBytes: 4 rowBytesAsPixels: 1 rowBytes: 5 rowBytesAsPixels: 1 rowBytes: 6 rowBytesAsPixels: 1 rowBytes: 7 rowBytesAsPixels: 1 rowBytes: 8 rowBytesAsPixels: 2 ## ## #SeeAlso rowBytes shiftPerPixel width bytesPerPixel ## # ------------------------------------------------------------------------------ #Method int shiftPerPixel() const #Line # returns bit shift from pixels to bytes ## Returns bit shift converting row bytes to row pixels. Returns zero for kUnknown_SkColorType. #Return one of: 0, 1, 2, 3; left shift to convert pixels to bytes ## #Example const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x", "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"}; SkImageInfo info = SkImageInfo::MakeA8(1, 1); SkBitmap bitmap; for (SkColorType colorType : { kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType, kARGB_4444_SkColorType, kRGBA_8888_SkColorType, kBGRA_8888_SkColorType, kGray_8_SkColorType, kRGBA_F16_SkColorType } ) { bitmap.setInfo(info.makeColorType(colorType)); SkDebugf("color: k" "%s" "_SkColorType" "%*s" "shiftPerPixel: %d\n", colors[colorType], 10 - strlen(colors[colorType]), " ", bitmap.shiftPerPixel()); } #StdOut color: kUnknown_SkColorType shiftPerPixel: 0 color: kAlpha_8_SkColorType shiftPerPixel: 0 color: kRGB_565_SkColorType shiftPerPixel: 1 color: kARGB_4444_SkColorType shiftPerPixel: 1 color: kRGBA_8888_SkColorType shiftPerPixel: 2 color: kBGRA_8888_SkColorType shiftPerPixel: 2 color: kGray_8_SkColorType shiftPerPixel: 0 color: kRGBA_F16_SkColorType shiftPerPixel: 3 ## ## #SeeAlso rowBytes rowBytesAsPixels width bytesPerPixel ## # ------------------------------------------------------------------------------ #Method bool empty() const #Line # returns true if Image_Info has zero width() or height() ## Returns true if either width() or height() are zero. Does not check if Pixel_Ref is nullptr; call drawsNothing to check width(), height(), and Pixel_Ref. #Return true if dimensions do not enclose area ## #Example SkBitmap bitmap; for (int width : { 0, 2 } ) { for (int height : { 0, 2 } ) { bitmap.setInfo(SkImageInfo::MakeA8(width, height)); SkDebugf("width: %d height: %d empty: %s\n", width, height, bitmap.empty() ? "true" : "false"); } } #StdOut width: 0 height: 0 empty: true width: 0 height: 2 empty: true width: 2 height: 0 empty: true width: 2 height: 2 empty: false ## ## #SeeAlso height() width() drawsNothing ## # ------------------------------------------------------------------------------ #Method bool isNull() const #Line # returns true if Pixel_Ref is nullptr ## Return true if Pixel_Ref is nullptr. Does not check if width() or height() are zero; call drawsNothing to check width(), height(), and Pixel_Ref. #Return true if no Pixel_Ref is associated ## #Example SkBitmap bitmap; SkDebugf("empty bitmap does %shave pixels\n", bitmap.isNull() ? "not " : ""); bitmap.setInfo(SkImageInfo::MakeA8(8, 8)); SkDebugf("bitmap with dimensions does %shave pixels\n", bitmap.isNull() ? "not " : ""); bitmap.allocPixels(); SkDebugf("allocated bitmap does %shave pixels\n", bitmap.isNull() ? "not " : ""); #StdOut empty bitmap does not have pixels bitmap with dimensions does not have pixels allocated bitmap does have pixels ## ## #SeeAlso empty() drawsNothing pixelRef ## # ------------------------------------------------------------------------------ #Method bool drawsNothing() const #Line # returns true if no width(), no height(), or no Pixel_Ref ## Return true if width() or height() are zero, or if Pixel_Ref is nullptr. If true, Bitmap has no effect when drawn or drawn into. #Return true if drawing has no effect ## #Example SkBitmap bitmap; for (int w : { 0, 8 } ) { for (bool allocate : { false, true} ) { bitmap.setInfo(SkImageInfo::MakeA8(w, 8)); allocate ? bitmap.allocPixels() : (void) 0 ; SkDebugf("empty:%s isNull:%s drawsNothing:%s\n", bitmap.empty() ? "true " : "false", bitmap.isNull() ? "true " : "false", bitmap.drawsNothing() ? "true" : "false"); } } #StdOut empty:true isNull:true drawsNothing:true empty:true isNull:false drawsNothing:true empty:false isNull:true drawsNothing:true empty:false isNull:false drawsNothing:false ## ## #SeeAlso empty() isNull pixelRef ## # ------------------------------------------------------------------------------ #Method size_t rowBytes() const #Line # returns interval between rows in bytes ## Returns row bytes, the interval from one pixel row to the next. Row bytes is at least as large as #Formula width() * info().bytesPerPixel() ## . Returns zero if colorType is kUnknown_SkColorType, or if row bytes supplied to setInfo is not large enough to hold a row of pixels. #Return byte length of pixel row ## #Example SkBitmap bitmap; for (int rowBytes : { 2, 8 } ) { bool result = bitmap.setInfo(SkImageInfo::MakeA8(4, 4), rowBytes); SkDebugf("setInfo returned:%s rowBytes:%d\n", result ? "true " : "false", bitmap.rowBytes()); } #StdOut setInfo returned:false rowBytes:0 setInfo returned:true rowBytes:8 ## ## #SeeAlso info() setInfo SkImageInfo::minRowBytes ## # ------------------------------------------------------------------------------ #Method bool setAlphaType(SkAlphaType alphaType) #Line # sets Alpha_Type of shared pixels ## Sets Alpha_Type, if alphaType is compatible with Color_Type. Returns true unless alphaType is kUnknown_SkAlphaType and current Alpha_Type is not kUnknown_SkAlphaType. Returns true if Color_Type is kUnknown_SkColorType. alphaType is ignored, and Alpha_Type remains kUnknown_SkAlphaType. Returns true if Color_Type is kRGB_565_SkColorType or kGray_8_SkColorType. alphaType is ignored, and Alpha_Type remains kOpaque_SkAlphaType. If Color_Type is kARGB_4444_SkColorType, kRGBA_8888_SkColorType, kBGRA_8888_SkColorType, or kRGBA_F16_SkColorType: returns true unless alphaType is kUnknown_SkAlphaType and Alpha_Type is not kUnknown_SkAlphaType. If Alpha_Type is kUnknown_SkAlphaType, alphaType is ignored. If Color_Type is kAlpha_8_SkColorType, returns true unless alphaType is kUnknown_SkAlphaType and Alpha_Type is not kUnknown_SkAlphaType. If Alpha_Type is kUnknown_SkAlphaType, alphaType is ignored. If alphaType is kUnpremul_SkAlphaType, it is treated as kPremul_SkAlphaType. This changes Alpha_Type in Pixel_Ref; all bitmaps sharing Pixel_Ref are affected. #Param alphaType one of: kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType, kUnpremul_SkAlphaType ## #Return true if Alpha_Type is set ## #Example void draw(SkCanvas* canvas) { const char* colors[] = { "Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x", "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16" }; const char* alphas[] = {"Unknown ", "Opaque ", "Premul ", "Unpremul"}; SkBitmap bitmap; SkAlphaType alphaTypes[] = { kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType, kUnpremul_SkAlphaType }; SkDebugf("%88s", "Canonical Unknown Opaque Premul Unpremul\n"); for (SkColorType colorType : { kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType, kARGB_4444_SkColorType, kRGBA_8888_SkColorType, kBGRA_8888_SkColorType, kGray_8_SkColorType, kRGBA_F16_SkColorType } ) { for (SkAlphaType canonicalAlphaType : alphaTypes) { SkColorTypeValidateAlphaType(colorType, kUnknown_SkAlphaType, &canonicalAlphaType ); SkDebugf("%10s %10s ", colors[(int) colorType], alphas[(int) canonicalAlphaType ]); for (SkAlphaType alphaType : alphaTypes) { bitmap.setInfo(SkImageInfo::Make(4, 4, colorType, canonicalAlphaType)); bool result = bitmap.setAlphaType(alphaType); SkDebugf("%s %s ", result ? "true " : "false", alphas[(int) bitmap.alphaType()]); } SkDebugf("\n"); } } } ## #SeeAlso Alpha_Type Color_Type Image_Info setInfo ## # ------------------------------------------------------------------------------ #Method void* getPixels() const #Line # returns address of pixels ## Returns pixel address, the base address corresponding to the pixel origin. #Return pixel address ## #Example SkBitmap bitmap; bitmap.setInfo(SkImageInfo::MakeN32(4, 4, kPremul_SkAlphaType)); bitmap.allocPixels(); bitmap.eraseColor(0x00000000); void* baseAddr = bitmap.getPixels(); *(SkPMColor*)baseAddr = 0xFFFFFFFF; SkDebugf("bitmap.getColor(0, 1) %c= 0x00000000\n", bitmap.getColor(0, 1) == 0x00000000 ? '=' : '!'); SkDebugf("bitmap.getColor(0, 0) %c= 0xFFFFFFFF\n", bitmap.getColor(0, 0) == 0xFFFFFFFF ? '=' : '!'); #StdOut bitmap.getColor(0, 1) == 0x00000000 bitmap.getColor(0, 0) == 0xFFFFFFFF ## ## #SeeAlso isNull drawsNothing ## # ------------------------------------------------------------------------------ #Method size_t computeByteSize() const #Line # returns size required for pixels ## Returns minimum memory required for pixel storage. Does not include unused memory on last row when rowBytesAsPixels exceeds width(). Returns zero if result does not fit in size_t. Returns zero if height() or width() is 0. Returns height() times rowBytes if colorType is kUnknown_SkColorType. #Return size in bytes of image buffer ## #Example SkBitmap bitmap; for (int width : { 1, 1000, 1000000 } ) { for (int height: { 1, 1000, 1000000 } ) { SkImageInfo imageInfo = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType); bitmap.setInfo(imageInfo, width * 5); SkDebugf("width: %7d height: %7d computeByteSize: %13lld\n", width, height, bitmap.computeByteSize()); } } #StdOut width: 1 height: 1 computeByteSize: 4 width: 1 height: 1000 computeByteSize: 4999 width: 1 height: 1000000 computeByteSize: 4999999 width: 1000 height: 1 computeByteSize: 4000 width: 1000 height: 1000 computeByteSize: 4999000 width: 1000 height: 1000000 computeByteSize: 4999999000 width: 1000000 height: 1 computeByteSize: 4000000 width: 1000000 height: 1000 computeByteSize: 4999000000 width: 1000000 height: 1000000 computeByteSize: 4999999000000 ## ## #SeeAlso SkImageInfo::computeByteSize ## # ------------------------------------------------------------------------------ #Method bool isImmutable() const #Line # returns true if pixels will not change ## Returns true if pixels can not change. Most immutable Bitmap checks trigger an assert only on debug builds. #Return true if pixels are immutable ## #Example SkBitmap original; SkImageInfo info = SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType); if (original.tryAllocPixels(info)) { original.setImmutable(); SkBitmap copy; original.extractSubset(©, {5, 10, 15, 20}); SkDebugf("original is " "%s" "immutable\n", original.isImmutable() ? "" : "not "); SkDebugf("copy is " "%s" "immutable\n", copy.isImmutable() ? "" : "not "); } #StdOut original is immutable copy is immutable ## ## #SeeAlso setImmutable SkPixelRef::isImmutable SkImage ## # ------------------------------------------------------------------------------ #Method void setImmutable() #Line # marks that pixels will not change ## Sets internal flag to mark Bitmap as immutable. Once set, pixels can not change. Any other bitmap sharing the same Pixel_Ref are also marked as immutable. Once Pixel_Ref is marked immutable, the setting cannot be cleared. Writing to immutable Bitmap pixels triggers an assert on debug builds. #Example #Description Triggers assert if SK_DEBUG is true, runs fine otherwise. ## SkBitmap bitmap; bitmap.setInfo(SkImageInfo::MakeN32(4, 4, kPremul_SkAlphaType)); bitmap.allocPixels(); SkCanvas offscreen(bitmap); SkDebugf("draw white\n"); offscreen.clear(SK_ColorWHITE); bitmap.setImmutable(); SkDebugf("draw black\n"); offscreen.clear(SK_ColorBLACK); ## #SeeAlso isImmutable SkPixelRef::setImmutable SkImage ## # ------------------------------------------------------------------------------ #Method bool isOpaque() const #Line # returns true if Image_Info describes opaque pixels ## Returns true if Alpha_Type is kOpaque_SkAlphaType. Does not check if Color_Type allows Alpha, or if any pixel value has transparency. #Return true if Image_Info describes opaque Alpha ## #Example #Description isOpaque ignores whether all pixels are opaque or not. ## const int height = 2; const int width = 2; SkBitmap bitmap; bitmap.setInfo(SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType)); for (int index = 0; index < 2; ++index) { bitmap.allocPixels(); bitmap.eraseColor(0x00000000); SkDebugf("isOpaque: %s\n", bitmap.isOpaque() ? "true" : "false"); bitmap.eraseColor(0xFFFFFFFF); SkDebugf("isOpaque: %s\n", bitmap.isOpaque() ? "true" : "false"); bitmap.setInfo(bitmap.info().makeAlphaType(kOpaque_SkAlphaType)); } #StdOut isOpaque: false isOpaque: false isOpaque: true isOpaque: true ## ## #SeeAlso ComputeIsOpaque SkImageInfo::isOpaque ## # ------------------------------------------------------------------------------ #Method bool isVolatile() const #Line # returns true if pixels should not be cached ## If true, provides a hint to caller that pixels should not be cached. Only true if setIsVolatile has been called to mark as volatile. Volatile state is not shared by other bitmaps sharing the same Pixel_Ref. #Return true if marked volatile ## #Example SkBitmap original; SkImageInfo info = SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType); if (original.tryAllocPixels(info)) { original.setIsVolatile(true); SkBitmap copy; original.extractSubset(©, {5, 10, 15, 20}); SkDebugf("original is " "%s" "volatile\n", original.isVolatile() ? "" : "not "); SkDebugf("copy is " "%s" "volatile\n", copy.isImmutable() ? "" : "not "); } #StdOut original is volatile copy is not volatile ## ## #SeeAlso setIsVolatile ## # ------------------------------------------------------------------------------ #Method void setIsVolatile(bool isVolatile) #Line # marks if pixels should not be cached ## Sets if pixels should be read from Pixel_Ref on every access. Bitmaps are not volatile by default; a GPU back end may upload pixel values expecting them to be accessed repeatedly. Marking temporary Bitmaps as volatile provides a hint to Device that the Bitmap pixels should not be cached. This can improve performance by avoiding overhead and reducing resource consumption on Device. #Param isVolatile true if backing pixels are temporary ## #Example #Height 20 SkBitmap bitmap; bitmap.setInfo(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType)); bitmap.allocPixels(); bitmap.eraseColor(SK_ColorRED); canvas->scale(16, 16); canvas->drawBitmap(bitmap, 0, 0); *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorBLUE); canvas->drawBitmap(bitmap, 2, 0); bitmap.setIsVolatile(true); *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorGREEN); canvas->drawBitmap(bitmap, 4, 0); ## #SeeAlso isVolatile ## # ------------------------------------------------------------------------------ #Method void reset() #Line # sets to default values, releases pixel ownership ## Resets to its initial state; all fields are set to zero, as if Bitmap had been initialized by SkBitmap(). Sets width, height, row bytes to zero; pixel address to nullptr; SkColorType to kUnknown_SkColorType; and SkAlphaType to kUnknown_SkAlphaType. If Pixel_Ref is allocated, its reference count is decreased by one, releasing its memory if Bitmap is the sole owner. #Example SkBitmap bitmap; bitmap.setInfo(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType)); bitmap.allocPixels(); SkDebugf("width:%d height:%d isNull:%s\n", bitmap.width(), bitmap.height(), bitmap.isNull() ? "true" : "false"); bitmap.reset(); SkDebugf("width:%d height:%d isNull:%s\n", bitmap.width(), bitmap.height(), bitmap.isNull() ? "true" : "false"); #StdOut width:1 height:1 isNull:false width:0 height:0 isNull:true ## ## #SeeAlso SkBitmap() SkAlphaType SkColorType ## # ------------------------------------------------------------------------------ #Method static bool ComputeIsOpaque(const SkBitmap& bm) #Line # returns true if all pixels are opaque ## Returns true if all pixels are opaque. Color_Type determines how pixels are encoded, and whether pixel describes Alpha. Returns true for Color_Types without alpha in each pixel; for other Color_Types, returns true if all pixels have alpha values equivalent to 1.0 or greater. For Color_Types kRGB_565_SkColorType or kGray_8_SkColorType: always returns true. For Color_Types kAlpha_8_SkColorType, kBGRA_8888_SkColorType, kRGBA_8888_SkColorType: returns true if all pixel Alpha values are 255. For Color_Type kARGB_4444_SkColorType: returns true if all pixel Alpha values are 15. For kRGBA_F16_SkColorType: returns true if all pixel Alpha values are 1.0 or greater. Returns false for kUnknown_SkColorType. #Param bm Bitmap to check ## #Return true if all pixels have opaque values or Color_Type is opaque ## #Example SkBitmap bitmap; bitmap.setInfo(SkImageInfo::Make(2, 2, kN32_SkColorType, kPremul_SkAlphaType)); for (int index = 0; index < 2; ++index) { bitmap.allocPixels(); bitmap.eraseColor(0x00000000); SkDebugf("computeIsOpaque: %s\n", SkBitmap::ComputeIsOpaque(bitmap) ? "true" : "false"); bitmap.eraseColor(0xFFFFFFFF); SkDebugf("computeIsOpaque: %s\n", SkBitmap::ComputeIsOpaque(bitmap) ? "true" : "false"); bitmap.setInfo(bitmap.info().makeAlphaType(kOpaque_SkAlphaType)); } #StdOut computeIsOpaque: false computeIsOpaque: true computeIsOpaque: false computeIsOpaque: true ## ## #SeeAlso isOpaque Color_Type Alpha ## # ------------------------------------------------------------------------------ #Method void getBounds(SkRect* bounds) const #Line # returns width() and height() as Rectangle ## Returns Rect { 0, 0, width(), height() }. #Param bounds container for floating point rectangle ## #Example #Height 160 #Image 3 SkRect bounds; source.getBounds(&bounds); bounds.offset(100, 100); SkPaint paint; paint.setColor(SK_ColorGRAY); canvas->scale(.25f, .25f); canvas->drawRect(bounds, paint); canvas->drawBitmap(source, 40, 40); ## #SeeAlso bounds() ## # ------------------------------------------------------------------------------ #Method void getBounds(SkIRect* bounds) const Returns IRect { 0, 0, width(), height() }. #Param bounds container for integral rectangle ## #Example #Image 3 SkIRect bounds; source.getBounds(&bounds); bounds.inset(100, 100); SkBitmap bitmap; source.extractSubset(&bitmap, bounds); canvas->scale(.5f, .5f); canvas->drawBitmap(bitmap, 10, 10); ## #SeeAlso bounds() ## # ------------------------------------------------------------------------------ #Method SkIRect bounds() const #Line # returns width() and height() as Rectangle ## Returns IRect { 0, 0, width(), height() }. #Return integral rectangle from origin to width() and height() ## #Example #Height 128 #Image 4 canvas->scale(.5f, .5f); SkIRect bounds = source.bounds(); for (int x : { 0, bounds.width() } ) { for (int y : { 0, bounds.height() } ) { canvas->drawBitmap(source, x, y); } } ## #SeeAlso getBounds ## # ------------------------------------------------------------------------------ #Method SkISize dimensions() const #Line # returns width() and height() ## Returns ISize { width(), height() }. #Return integral size of width() and height() ## #Example SkBitmap bitmap; bitmap.setInfo(SkImageInfo::MakeN32(33, 55, kOpaque_SkAlphaType)); SkISize dimensions = bitmap.dimensions(); SkRect bounds; bitmap.getBounds(&bounds); SkRect dimensionsAsBounds = SkRect::Make(dimensions); SkDebugf("dimensionsAsBounds %c= bounds\n", dimensionsAsBounds == bounds ? '=' : '!'); ## #SeeAlso height() width() ## # ------------------------------------------------------------------------------ #Method SkIRect getSubset() const #Line # returns bounds offset by origin ## Returns the bounds of this bitmap, offset by its Pixel_Ref origin. #Return bounds within Pixel_Ref bounds ## #Example #Image 3 SkIRect bounds; source.getBounds(&bounds); bounds.inset(100, 100); SkBitmap subset; source.extractSubset(&subset, bounds); SkIRect r = source.getSubset(); SkDebugf("source: %d, %d, %d, %d\n", r.fLeft, r.fTop, r.fRight, r.fBottom); r = subset.getSubset(); SkDebugf("subset: %d, %d, %d, %d\n", r.fLeft, r.fTop, r.fRight, r.fBottom); #StdOut source: 0, 0, 512, 512 subset: 100, 100, 412, 412 ## ## #SeeAlso extractSubset getBounds ## # ------------------------------------------------------------------------------ #Method bool setInfo(const SkImageInfo& imageInfo, size_t rowBytes = 0) #Line # sets height, width, Color_Type, and so on, releasing pixels ## Sets width, height, Alpha_Type, Color_Type, Color_Space, and optional rowBytes. Frees pixels, and returns true if successful. imageInfo.alphaType may be altered to a value permitted by imageInfo.colorSpace. If imageInfo.colorType is kUnknown_SkColorType, imageInfo.alphaType is set to kUnknown_SkAlphaType. If imageInfo.colorType is kAlpha_8_SkColorType and imageInfo.alphaType is kUnpremul_SkAlphaType, imageInfo.alphaType is replaced by kPremul_SkAlphaType. If imageInfo.colorType is kRGB_565_SkColorType or kGray_8_SkColorType, imageInfo.alphaType is set to kOpaque_SkAlphaType. If imageInfo.colorType is kARGB_4444_SkColorType, kRGBA_8888_SkColorType, kBGRA_8888_SkColorType, or kRGBA_F16_SkColorType: imageInfo.alphaType remains unchanged. rowBytes must equal or exceed imageInfo.minRowBytes. If imageInfo.colorSpace is kUnknown_SkColorType, rowBytes is ignored and treated as zero; for all other Color_Space values, rowBytes of zero is treated as imageInfo.minRowBytes. Calls reset() and returns false if: #List # rowBytes exceeds 31 bits ## # imageInfo.width() is negative ## # imageInfo.height() is negative ## # rowBytes is positive and less than imageInfo.width() times imageInfo.bytesPerPixel ## ## #Param imageInfo contains width, height, Alpha_Type, Color_Type, Color_Space ## #Param rowBytes imageInfo.minRowBytes or larger; or zero ## #Return true if Image_Info set successfully ## #Example #Height 96 ###^ SkBitmap bitmap; bitmap.setInfo(SkImageInfo::MakeN32(44, 16, kOpaque_SkAlphaType)); bitmap.allocPixels(); bitmap.eraseColor(SK_ColorGREEN); SkCanvas offscreen(bitmap); SkPaint paint; offscreen.drawString("!@#$%", 0, 12, paint); canvas->scale(6, 6); canvas->drawBitmap(bitmap, 0, 0); ^^^# ## #SeeAlso Alpha_Type Color_Type Color_Space height rowBytes width ## # ------------------------------------------------------------------------------ #Enum AllocFlags #Code enum AllocFlags { kZeroPixels_AllocFlag = 1 << 0, }; ## AllocFlags provides the option to zero pixel memory when allocated. #Const kZeroPixels_AllocFlag 1 Instructs tryAllocPixelsFlags and allocPixelsFlags to zero pixel memory. ## #NoExample ## #SeeAlso tryAllocPixelsFlags allocPixelsFlags erase() eraseColor ## # ------------------------------------------------------------------------------ #Method bool SK_WARN_UNUSED_RESULT tryAllocPixelsFlags(const SkImageInfo& info, uint32_t flags) #Line # allocates pixels from Image_Info with options if possible ## Sets Image_Info to info following the rules in setInfo and allocates pixel memory. If flags is kZeroPixels_AllocFlag, memory is zeroed. Returns false and calls reset() if Image_Info could not be set, or memory could not be allocated, or memory could not optionally be zeroed. On most platforms, allocating pixel memory may succeed even though there is not sufficient memory to hold pixels; allocation does not take place until the pixels are written to. The actual behavior depends on the platform implementation of malloc(), if flags is zero, and calloc(), if flags is kZeroPixels_AllocFlag. Passing kZeroPixels_AllocFlag is usually faster than separately calling eraseColor(SK_ColorTRANSPARENT). #Param info contains width, height, Alpha_Type, Color_Type, Color_Space ## #Param flags kZeroPixels_AllocFlag, or zero ## #Return true if pixels allocation is successful ## #Example SkBitmap bitmap; if (!bitmap.tryAllocPixelsFlags(SkImageInfo::MakeN32(10000, 10000, kOpaque_SkAlphaType), SkBitmap::kZeroPixels_AllocFlag)) { SkDebugf("bitmap allocation failed!\n"); } else { SkDebugf("bitmap allocation succeeded!\n"); } #StdOut bitmap allocation succeeded! ## ## #SeeAlso allocPixelsFlags tryAllocPixels SkMallocPixelRef::MakeZeroed ## # ------------------------------------------------------------------------------ #Method void allocPixelsFlags(const SkImageInfo& info, uint32_t flags) #Line # allocates pixels from Image_Info with options, or aborts ## Sets Image_Info to info following the rules in setInfo and allocates pixel memory. If flags is kZeroPixels_AllocFlag, memory is zeroed. Aborts execution if Image_Info could not be set, or memory could not be allocated, or memory could not optionally be zeroed. Abort steps may be provided by the user at compile time by defining SK_ABORT. On most platforms, allocating pixel memory may succeed even though there is not sufficient memory to hold pixels; allocation does not take place until the pixels are written to. The actual behavior depends on the platform implementation of malloc(), if flags is zero, and calloc(), if flags is kZeroPixels_AllocFlag. Passing kZeroPixels_AllocFlag is usually faster than separately calling eraseColor(SK_ColorTRANSPARENT). #Param info contains width, height, Alpha_Type, Color_Type, Color_Space ## #Param flags kZeroPixels_AllocFlag, or zero ## #Example #Height 128 #Description Text is drawn on a transparent background; drawing the bitmap a second time lets the first draw show through. ## ###^ SkBitmap bitmap; bitmap.allocPixelsFlags(SkImageInfo::MakeN32(44, 16, kPremul_SkAlphaType), SkBitmap::kZeroPixels_AllocFlag); SkCanvas offscreen(bitmap); SkPaint paint; offscreen.drawString("!@#$%", 0, 12, paint); canvas->scale(6, 6); canvas->drawBitmap(bitmap, 0, 0); canvas->drawBitmap(bitmap, 8, 8); ^^^# ## #SeeAlso tryAllocPixelsFlags allocPixels SkMallocPixelRef::MakeZeroed ## # ------------------------------------------------------------------------------ #Method bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info, size_t rowBytes) #Line # allocates pixels from Image_Info if possible ## #ToDo am I ever conflicted about setInfo rules. It needs to be able to be replicated if, for instance, I generate one-page-per-method HTML-style documentation I'm not so sure it makes sense to put the indirection in for .h either unless my mantra is that .h should abbreviate full documentation. And, what to do for generated markdown? At least there the rules are a click away, although a pop-down in place would be way better. Hmmm. ## Sets Image_Info to info following the rules in setInfo and allocates pixel memory. rowBytes must equal or exceed info.width() times info.bytesPerPixel(), or equal zero. Pass in zero for rowBytes to compute the minimum valid value. Returns false and calls reset() if Image_Info could not be set, or memory could not be allocated. On most platforms, allocating pixel memory may succeed even though there is not sufficient memory to hold pixels; allocation does not take place until the pixels are written to. The actual behavior depends on the platform implementation of malloc(). #Param info contains width, height, Alpha_Type, Color_Type, Color_Space ## #Param rowBytes size of pixel row or larger; may be zero ## #Return true if pixel storage is allocated ## #Example #Image 3 SkBitmap bitmap; SkImageInfo info = SkImageInfo::Make(64, 256, kGray_8_SkColorType, kOpaque_SkAlphaType); if (bitmap.tryAllocPixels(info, 0)) { SkCanvas offscreen(bitmap); offscreen.scale(.5f, .5f); for (int x : { 0, 64, 128, 192 } ) { offscreen.drawBitmap(source, -x, 0); canvas->drawBitmap(bitmap, x, 0); } } ## #SeeAlso tryAllocPixelsFlags allocPixels SkMallocPixelRef::MakeAllocate ## # ------------------------------------------------------------------------------ #Method void allocPixels(const SkImageInfo& info, size_t rowBytes) #Line # allocates pixels from Image_Info, or aborts ## Sets Image_Info to info following the rules in setInfo and allocates pixel memory. rowBytes must equal or exceed info.width() times info.bytesPerPixel(), or equal zero. Pass in zero for rowBytes to compute the minimum valid value. Aborts execution if Image_Info could not be set, or memory could not be allocated. Abort steps may be provided by the user at compile time by defining SK_ABORT. On most platforms, allocating pixel memory may succeed even though there is not sufficient memory to hold pixels; allocation does not take place until the pixels are written to. The actual behavior depends on the platform implementation of malloc(). #Param info contains width, height, Alpha_Type, Color_Type, Color_Space ## #Param rowBytes size of pixel row or larger; may be zero ## #Example #Image 3 SkBitmap bitmap; SkImageInfo info = SkImageInfo::Make(256, 64, kGray_8_SkColorType, kOpaque_SkAlphaType); bitmap.allocPixels(info, info.width() * info.bytesPerPixel() + 64); SkCanvas offscreen(bitmap); offscreen.scale(.5f, .5f); for (int y : { 0, 64, 128, 192 } ) { offscreen.drawBitmap(source, 0, -y); canvas->drawBitmap(bitmap, 0, y); } ## #SeeAlso tryAllocPixels allocPixelsFlags SkMallocPixelRef::MakeAllocate ## # ------------------------------------------------------------------------------ #Method bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info) Sets Image_Info to info following the rules in setInfo and allocates pixel memory. Returns false and calls reset() if Image_Info could not be set, or memory could not be allocated. On most platforms, allocating pixel memory may succeed even though there is not sufficient memory to hold pixels; allocation does not take place until the pixels are written to. The actual behavior depends on the platform implementation of malloc(). #Param info contains width, height, Alpha_Type, Color_Type, Color_Space ## #Return true if pixel storage is allocated ## #Example #Image 3 SkBitmap bitmap; if (bitmap.tryAllocPixels(SkImageInfo::Make(64, 64, kGray_8_SkColorType, kOpaque_SkAlphaType))) { SkCanvas offscreen(bitmap); offscreen.scale(.25f, .5f); for (int y : { 0, 64, 128, 192 } ) { offscreen.drawBitmap(source, -y, -y); canvas->drawBitmap(bitmap, y, y); } } ## #SeeAlso tryAllocPixelsFlags allocPixels SkMallocPixelRef::MakeAllocate ## # ------------------------------------------------------------------------------ #Method void allocPixels(const SkImageInfo& info) Sets Image_Info to info following the rules in setInfo and allocates pixel memory. Aborts execution if Image_Info could not be set, or memory could not be allocated. Abort steps may be provided by the user at compile time by defining SK_ABORT. On most platforms, allocating pixel memory may succeed even though there is not sufficient memory to hold pixels; allocation does not take place until the pixels are written to. The actual behavior depends on the platform implementation of malloc(). #Param info contains width, height, Alpha_Type, Color_Type, Color_Space ## #Example #Image 4 SkBitmap bitmap; bitmap.allocPixels(SkImageInfo::Make(64, 64, kGray_8_SkColorType, kOpaque_SkAlphaType)); SkCanvas offscreen(bitmap); offscreen.scale(.5f, .5f); for (int y : { 0, 64, 128, 192 } ) { offscreen.drawBitmap(source, -y, -y); canvas->drawBitmap(bitmap, y, y); } ## #SeeAlso tryAllocPixels allocPixelsFlags SkMallocPixelRef::MakeAllocate ## # ------------------------------------------------------------------------------ #Method bool SK_WARN_UNUSED_RESULT tryAllocN32Pixels(int width, int height, bool isOpaque = false) #Line # allocates compatible Color_ARGB pixels if possible ## Sets Image_Info to width, height, and Native_Color_Type; and allocates pixel memory. If isOpaque is true, sets Image_Info to kOpaque_SkAlphaType; otherwise, sets to kPremul_SkAlphaType. Calls reset() and returns false if width exceeds 29 bits or is negative, or height is negative. Returns false if allocation fails. Use to create Bitmap that matches SkPMColor, the native pixel arrangement on the platform. Bitmap drawn to output device skips converting its pixel format. #Param width pixel column count; must be zero or greater ## #Param height pixel row count; must be zero or greater ## #Param isOpaque true if pixels do not have transparency ## #Return true if pixel storage is allocated ## #Example #Height 160 SkBitmap bitmap; if (bitmap.tryAllocN32Pixels(80, 80)) { bitmap.eraseColor(SK_ColorTRANSPARENT); bitmap.erase(0x7f3f7fff, SkIRect::MakeWH(50, 30)); bitmap.erase(0x3f7fff3f, SkIRect::MakeXYWH(20, 10, 50, 30)); bitmap.erase(0x5fff3f7f, SkIRect::MakeXYWH(40, 20, 50, 30)); canvas->drawBitmap(bitmap, 0, 0); for (int x : { 0, 30, 60, 90 } ) { canvas->drawBitmap(bitmap, x, 70); } } ## #SeeAlso tryAllocPixels allocN32Pixels SkMallocPixelRef::MakeAllocate ## # ------------------------------------------------------------------------------ #Method void allocN32Pixels(int width, int height, bool isOpaque = false) #Line # allocates compatible Color_ARGB pixels, or aborts ## Sets Image_Info to width, height, and the Native_Color_Type; and allocates pixel memory. If isOpaque is true, sets Image_Info to kPremul_SkAlphaType; otherwise, sets to kOpaque_SkAlphaType. Aborts if width exceeds 29 bits or is negative, or height is negative, or allocation fails. Abort steps may be provided by the user at compile time by defining SK_ABORT. Use to create Bitmap that matches SkPMColor, the native pixel arrangement on the platform. Bitmap drawn to output device skips converting its pixel format. #Param width pixel column count; must be zero or greater ## #Param height pixel row count; must be zero or greater ## #Param isOpaque true if pixels do not have transparency ## #Example SkRandom random; SkBitmap bitmap; bitmap.allocN32Pixels(64, 64); bitmap.eraseColor(SK_ColorTRANSPARENT); for (int y = 0; y < 256; y += 64) { for (int x = 0; x < 256; x += 64) { SkColor color = random.nextU(); uint32_t w = random.nextRangeU(4, 32); uint32_t cx = random.nextRangeU(0, 64 - w); uint32_t h = random.nextRangeU(4, 32); uint32_t cy = random.nextRangeU(0, 64 - h); bitmap.erase(color, SkIRect::MakeXYWH(cx, cy, w, h)); canvas->drawBitmap(bitmap, x, y); } } ## #SeeAlso allocPixels tryAllocN32Pixels SkMallocPixelRef::MakeAllocate ## # ------------------------------------------------------------------------------ #Method bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, void (*releaseProc)(void* addr, void* context), void* context) #Line # creates Pixel_Ref, with optional release function ## Sets Image_Info to info following the rules in setInfo, and creates Pixel_Ref containing pixels and rowBytes. releaseProc, if not nullptr, is called immediately on failure or when pixels are no longer referenced. context may be nullptr. If Image_Info could not be set, or rowBytes is less than info.minRowBytes: calls releaseProc if present, calls reset(), and returns false. Otherwise, if pixels equals nullptr: sets Image_Info, calls releaseProc if present, returns true. If Image_Info is set, pixels is not nullptr, and releaseProc is not nullptr: when pixels are no longer referenced, calls releaseProc with pixels and context as parameters. #Param info contains width, height, Alpha_Type, Color_Type, Color_Space ## #Param pixels address or pixel storage; may be nullptr ## #Param rowBytes size of pixel row or larger ## #Param releaseProc function called when pixels can be deleted; may be nullptr ## #Param context caller state passed to releaseProc; may be nullptr ## #Return true if Image_Info is set to info ## #Example #Description releaseProc is called immediately because rowBytes is too small for Pixel_Ref. ## #Function static void releaseProc(void* addr, void* ) { SkDebugf("releaseProc called\n"); delete[] (uint32_t*) addr; } ## void draw(SkCanvas* canvas) { SkBitmap bitmap; void* pixels = new uint32_t[8 * 8]; SkImageInfo info = SkImageInfo::MakeN32(8, 8, kOpaque_SkAlphaType); SkDebugf("before installPixels\n"); bool installed = bitmap.installPixels(info, pixels, 16, releaseProc, nullptr); SkDebugf("install " "%s" "successful\n", installed ? "" : "not "); } #StdOut before installPixels releaseProc called install not successful ## ## #SeeAlso allocPixels ## # ------------------------------------------------------------------------------ #Method bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) Sets Image_Info to info following the rules in setInfo, and creates Pixel_Ref containing pixels and rowBytes. If Image_Info could not be set, or rowBytes is less than info.minRowBytes: calls reset(), and returns false. Otherwise, if pixels equals nullptr: sets Image_Info, returns true. Caller must ensure that pixels are valid for the lifetime of Bitmap and Pixel_Ref. #Param info contains width, height, Alpha_Type, Color_Type, Color_Space ## #Param pixels address or pixel storage; may be nullptr ## #Param rowBytes size of pixel row or larger ## #Return true if Image_Info is set to info ## #Example #Description #Bug 7079 ## GPU does not support kUnpremul_SkAlphaType, does not assert that it does not. ## void draw(SkCanvas* canvas) { SkRandom random; SkBitmap bitmap; const int width = 8; const int height = 8; uint32_t pixels[width * height]; for (unsigned x = 0; x < width * height; ++x) { pixels[x] = random.nextU(); } SkImageInfo info = SkImageInfo::MakeN32(width, height, kUnpremul_SkAlphaType); if (bitmap.installPixels(info, pixels, info.minRowBytes())) { canvas->scale(32, 32); canvas->drawBitmap(bitmap, 0, 0); } } ## #SeeAlso allocPixels ## # ------------------------------------------------------------------------------ #Method bool installPixels(const SkPixmap& pixmap) Sets Image_Info to pixmap.info() following the rules in setInfo, and creates Pixel_Ref containing pixmap.addr() and pixmap.rowBytes. If Image_Info could not be set, or pixmap.rowBytes is less than SkImageInfo::minRowBytes: calls reset(), and returns false. Otherwise, if pixmap.addr() equals nullptr: sets Image_Info, returns true. Caller must ensure that pixmap is valid for the lifetime of Bitmap and Pixel_Ref. #Param pixmap Image_Info, pixel address, and rowBytes ## #Return true if Image_Info was set to pixmap.info() ## #Example #Description Draw a five by five bitmap, and draw it again with a center white pixel. ## #Height 64 uint8_t storage[][5] = {{ 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 }, { 0xAC, 0xA8, 0x89, 0x47, 0x87 }, { 0x4B, 0x25, 0x25, 0x25, 0x46 }, { 0x90, 0x81, 0x25, 0x41, 0x33 }, { 0x75, 0x55, 0x44, 0x20, 0x00 }}; SkImageInfo imageInfo = SkImageInfo::Make(5, 5, kGray_8_SkColorType, kOpaque_SkAlphaType); SkPixmap pixmap(imageInfo, storage[0], sizeof(storage) / 5); SkBitmap bitmap; bitmap.installPixels(pixmap); canvas->scale(10, 10); canvas->drawBitmap(bitmap, 0, 0); *pixmap.writable_addr8(2, 2) = 0xFF; bitmap.installPixels(pixmap); canvas->drawBitmap(bitmap, 10, 0); ## #SeeAlso allocPixels ## # ------------------------------------------------------------------------------ #Method bool installMaskPixels(const SkMask& mask) #Line # creates Pixel_Ref from Mask ## Sets Image_Info to mask width, mask height, kAlpha_8_SkColorType, and kPremul_SkAlphaType. Sets Pixel_Ref to mask image and mask rowBytes. Returns false and calls reset() if mask format is not SkMask::kA8_Format, or if mask width or mask height is negative, or if mask rowBytes is less than mask width. Caller must ensure that mask is valid for the lifetime of Bitmap and Pixel_Ref. #Param mask Alpha 8-bit bitmap ## #Return true if Image_Info and Pixel_Ref refer to mask ## #Example #Description Draw a five by five bitmap, and draw it again with a center white pixel. ## #Height 64 uint8_t storage[][5] = {{ 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 }, { 0xAC, 0xA8, 0x89, 0x47, 0x87 }, { 0x4B, 0x25, 0x25, 0x25, 0x46 }, { 0x90, 0x81, 0x25, 0x41, 0x33 }, { 0x75, 0x55, 0x44, 0x20, 0x00 }}; SkMask mask; mask.fImage = storage[0]; mask.fBounds = SkIRect::MakeWH(5, 5); mask.fRowBytes = 5; mask.fFormat = SkMask::kA8_Format; SkBitmap bitmap; bitmap.installMaskPixels(mask); canvas->scale(10, 10); canvas->drawBitmap(bitmap, 0, 0); storage[2][2] = 0xFF; bitmap.installMaskPixels(mask); canvas->drawBitmap(bitmap, 10, 0); ## #SeeAlso installPixels allocPixels ## # ------------------------------------------------------------------------------ #Method void setPixels(void* pixels) #Line # sets Pixel_Ref without an offset ## Replaces Pixel_Ref with pixels, preserving Image_Info and rowBytes. Sets Pixel_Ref origin to (0, 0). If pixels is nullptr, or if info().colorType equals kUnknown_SkColorType; release reference to Pixel_Ref, and set Pixel_Ref to nullptr. Caller is responsible for handling ownership pixel memory for the lifetime of Bitmap and Pixel_Ref. #Param pixels address of pixel storage, managed by caller ## #Example #Height 50 uint8_t set1[5] = { 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 }; uint8_t set2[5] = { 0xAC, 0xA8, 0x89, 0x47, 0x87 }; SkBitmap bitmap; bitmap.installPixels(SkImageInfo::Make(5, 1, kGray_8_SkColorType, kOpaque_SkAlphaType), set1, 5); canvas->scale(10, 50); canvas->drawBitmap(bitmap, 0, 0); bitmap.setPixels(set2); canvas->drawBitmap(bitmap, 10, 0); ## #SeeAlso installPixels allocPixels ## # ------------------------------------------------------------------------------ #Method bool SK_WARN_UNUSED_RESULT tryAllocPixels() Allocates pixel memory with HeapAllocator, and replaces existing Pixel_Ref. The allocation size is determined by Image_Info width, height, and Color_Type. Returns false if info().colorType is kUnknown_SkColorType, or allocation fails. #Return true if the allocation succeeds ## #Example #Height 50 #Description Bitmap hosts and draws gray values in set1. tryAllocPixels replaces Pixel_Ref and erases it to black, but does not alter set1. setPixels replaces black Pixel_Ref with set1. ## uint8_t set1[5] = { 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 }; SkBitmap bitmap; bitmap.installPixels(SkImageInfo::Make(5, 1, kGray_8_SkColorType, kOpaque_SkAlphaType), set1, 5); canvas->scale(10, 50); canvas->drawBitmap(bitmap, 0, 0); if (bitmap.tryAllocPixels()) { bitmap.eraseColor(SK_ColorBLACK); canvas->drawBitmap(bitmap, 8, 0); bitmap.setPixels(set1); canvas->drawBitmap(bitmap, 16, 0); } ## #SeeAlso allocPixels installPixels setPixels ## # ------------------------------------------------------------------------------ #Method void allocPixels() Allocates pixel memory with HeapAllocator, and replaces existing Pixel_Ref. The allocation size is determined by Image_Info width, height, and Color_Type. Aborts if info().colorType is kUnknown_SkColorType, or allocation fails. Abort steps may be provided by the user at compile time by defining SK_ABORT. #Example #Height 50 #Description Bitmap hosts and draws gray values in set1. allocPixels replaces Pixel_Ref and erases it to black, but does not alter set1. setPixels replaces black Pixel_Ref with set2. ## uint8_t set1[5] = { 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 }; uint8_t set2[5] = { 0xAC, 0xA8, 0x89, 0x47, 0x87 }; SkBitmap bitmap; bitmap.installPixels(SkImageInfo::Make(5, 1, kGray_8_SkColorType, kOpaque_SkAlphaType), set1, 5); canvas->scale(10, 50); canvas->drawBitmap(bitmap, 0, 0); bitmap.allocPixels(); bitmap.eraseColor(SK_ColorBLACK); canvas->drawBitmap(bitmap, 8, 0); bitmap.setPixels(set2); canvas->drawBitmap(bitmap, 16, 0); ## #SeeAlso tryAllocPixels installPixels setPixels ## # ------------------------------------------------------------------------------ #Method bool SK_WARN_UNUSED_RESULT tryAllocPixels(Allocator* allocator) Allocates pixel memory with allocator, and replaces existing Pixel_Ref. The allocation size is determined by Image_Info width, height, and Color_Type. If allocator is nullptr, use HeapAllocator instead. Returns false if allocator allocPixelRef return false. #Param allocator instance of SkBitmap::Allocator instantiation ## #Return true if custom allocator reports success ## #Example #Height 100 #Description HeapAllocator limits the maximum size of Bitmap to two gigabytes. Using a custom allocator, this limitation may be relaxed. This example can be modified to allocate an eight gigabyte Bitmap on a 64 bit platform with sufficient memory. ## #Function class LargePixelRef : public SkPixelRef { public: LargePixelRef(const SkImageInfo& info, char* storage, size_t rowBytes) : SkPixelRef(info.width(), info.height(), storage, rowBytes) { } ~LargePixelRef() override { delete[] (char* ) this->pixels(); } }; class LargeAllocator : public SkBitmap::Allocator { public: bool allocPixelRef(SkBitmap* bitmap) override { const SkImageInfo& info = bitmap->info(); uint64_t rowBytes = info.minRowBytes64(); uint64_t size = info.height() * rowBytes; char* addr = new char[size]; if (nullptr == addr) { return false; } sk_sp<SkPixelRef> pr = sk_sp<SkPixelRef>(new LargePixelRef(info, addr, rowBytes)); if (!pr) { return false; } bitmap->setPixelRef(std::move(pr), 0, 0); return true; } }; ## void draw(SkCanvas* canvas) { LargeAllocator largeAllocator; SkBitmap bitmap; int width = 100; // make this 20000 int height = 100; // and this 100000 to allocate 8 gigs on a 64-bit platform bitmap.setInfo(SkImageInfo::MakeN32(width, height, kOpaque_SkAlphaType)); if (bitmap.tryAllocPixels(&largeAllocator)) { bitmap.eraseColor(0xff55aa33); canvas->drawBitmap(bitmap, 0, 0); } } ## #SeeAlso allocPixels Allocator Pixel_Ref ## # ------------------------------------------------------------------------------ #Method void allocPixels(Allocator* allocator) Allocates pixel memory with allocator, and replaces existing Pixel_Ref. The allocation size is determined by Image_Info width, height, and Color_Type. If allocator is nullptr, use HeapAllocator instead. Aborts if allocator allocPixelRef return false. Abort steps may be provided by the user at compile time by defining SK_ABORT. #Param allocator instance of SkBitmap::Allocator instantiation ## #Example #Height 32 #Function class TinyAllocator : public SkBitmap::Allocator { public: bool allocPixelRef(SkBitmap* bitmap) override { const SkImageInfo& info = bitmap->info(); if (info.height() * info.minRowBytes() > sizeof(storage)) { return false; } sk_sp<SkPixelRef> pr = sk_sp<SkPixelRef>( new SkPixelRef(info.width(), info.height(), storage, info.minRowBytes())); bitmap->setPixelRef(std::move(pr), 0, 0); return true; } char storage[16]; }; ## void draw(SkCanvas* canvas) { TinyAllocator tinyAllocator; SkBitmap bitmap; bitmap.setInfo(SkImageInfo::MakeN32(2, 2, kOpaque_SkAlphaType)); if (bitmap.tryAllocPixels(&tinyAllocator)) { bitmap.eraseColor(0xff55aa33); bitmap.erase(0xffaa3355, SkIRect::MakeXYWH(1, 1, 1, 1)); canvas->scale(16, 16); canvas->drawBitmap(bitmap, 0, 0); } } ## #SeeAlso allocPixels Allocator Pixel_Ref ## # ------------------------------------------------------------------------------ #Method SkPixelRef* pixelRef() const #Line # returns Pixel_Ref, or nullptr ## Returns Pixel_Ref, which contains: pixel base address; its dimensions; and rowBytes, the interval from one row to the next. Does not change Pixel_Ref reference count. Pixel_Ref may be shared by multiple bitmaps. If Pixel_Ref has not been set, returns nullptr. #Return Pixel_Ref, or nullptr ## #Example #Image 3 SkBitmap subset; source.extractSubset(&subset, SkIRect::MakeXYWH(32, 64, 128, 256)); SkDebugf("src ref %c= sub ref\n", source.pixelRef() == subset.pixelRef() ? '=' : '!'); SkDebugf("src pixels %c= sub pixels\n", source.getPixels() == subset.getPixels() ? '=' : '!'); SkDebugf("src addr %c= sub addr\n", source.getAddr(32, 64) == subset.getAddr(0, 0) ? '=' : '!'); ## #SeeAlso getPixels getAddr ## # ------------------------------------------------------------------------------ #Method SkIPoint pixelRefOrigin() const #Line # returns offset within Pixel_Ref ## Returns origin of pixels within Pixel_Ref. Bitmap bounds is always contained by Pixel_Ref bounds, which may be the same size or larger. Multiple Bitmaps can share the same Pixel_Ref, where each Bitmap has different bounds. The returned origin added to Bitmap dimensions equals or is smaller than the Pixel_Ref dimensions. Returns (0, 0) if Pixel_Ref is nullptr. #Return pixel origin within Pixel_Ref ## #Example #Image 3 SkBitmap subset; source.extractSubset(&subset, SkIRect::MakeXYWH(32, 64, 128, 256)); SkIPoint sourceOrigin = source.pixelRefOrigin(); SkIPoint subsetOrigin = subset.pixelRefOrigin(); SkDebugf("source origin: %d, %d\n", sourceOrigin.fX, sourceOrigin.fY); SkDebugf("subset origin: %d, %d\n", subsetOrigin.fX, subsetOrigin.fY); #StdOut source origin: 0, 0 subset origin: 32, 64 ## ## #SeeAlso SkPixelRef getSubset setPixelRef ## # ------------------------------------------------------------------------------ #Method void setPixelRef(sk_sp<SkPixelRef> pixelRef, int dx, int dy) #Line # sets Pixel_Ref and offset ## Replaces pixelRef and origin in Bitmap. dx and dy specify the offset within the Pixel_Ref pixels for the top-left corner of the bitmap. Asserts in debug builds if dx or dy are out of range. Pins dx and dy to legal range in release builds. The caller is responsible for ensuring that the pixels match the Color_Type and Alpha_Type in Image_Info. #Param pixelRef Pixel_Ref describing pixel address and rowBytes ## #Param dx column offset in Pixel_Ref for bitmap origin ## #Param dy row offset in Pixel_Ref for bitmap origin ## #Example #Height 140 #Image 5 #Description Treating 32 bit data as 8 bit data is unlikely to produce useful results. ## SkBitmap bitmap; bitmap.setInfo(SkImageInfo::Make(source.width() - 5, source.height() - 5, kGray_8_SkColorType, kOpaque_SkAlphaType), source.rowBytes()); bitmap.setPixelRef(sk_ref_sp(source.pixelRef()), 5, 5); canvas->drawBitmap(bitmap, 10, 10); ## #SeeAlso setInfo ## # ------------------------------------------------------------------------------ #Method bool readyToDraw() const #Line # returns true if address of pixels is not nullptr ## Returns true if Bitmap is can be drawn. #Return true if getPixels() is not nullptr ## #Example #Image 5 #Height 160 if (source.readyToDraw()) { canvas->drawBitmap(source, 10, 10); } ## #SeeAlso getPixels drawsNothing ## # ------------------------------------------------------------------------------ #Method uint32_t getGenerationID() const #Line # returns unique ID ## Returns a unique value corresponding to the pixels in Pixel_Ref. Returns a different value after notifyPixelsChanged has been called. Returns zero if Pixel_Ref is nullptr. Determines if pixels have changed since last examined. #Return unique value for pixels in Pixel_Ref ## #Example SkBitmap bitmap; SkDebugf("empty id %u\n", bitmap.getGenerationID()); bitmap.allocPixels(SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType)); SkDebugf("alloc id %u\n", bitmap.getGenerationID()); bitmap.eraseColor(SK_ColorRED); SkDebugf("erase id %u\n", bitmap.getGenerationID()); #StdOut #Volatile empty id 0 alloc id 4 erase id 6 ## ## #SeeAlso notifyPixelsChanged Pixel_Ref ## # ------------------------------------------------------------------------------ #Method void notifyPixelsChanged() const #Line # marks pixels as changed, altering the unique ID ## Marks that pixels in Pixel_Ref have changed. Subsequent calls to getGenerationID() return a different value. #Example #Height 20 SkBitmap bitmap; bitmap.setInfo(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType)); bitmap.allocPixels(); bitmap.eraseColor(SK_ColorRED); canvas->scale(16, 16); canvas->drawBitmap(bitmap, 0, 0); *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorBLUE); canvas->drawBitmap(bitmap, 2, 0); bitmap.notifyPixelsChanged(); *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorGREEN); canvas->drawBitmap(bitmap, 4, 0); ## #SeeAlso getGenerationID isVolatile Pixel_Ref ## # ------------------------------------------------------------------------------ #Method void eraseColor(SkColor c) const #Line # writes Color to pixels ## Replaces pixel values with c. All pixels contained by bounds() are affected. If the colorType is kGray_8_SkColorType or k565_SkColorType, then Color_Alpha is ignored; Color_RGB is treated as opaque. If colorType is kAlpha_8_SkColorType, then Color_RGB is ignored. #Param c Unpremultiplied Color ## #Example #Height 20 SkBitmap bitmap; bitmap.allocPixels(SkImageInfo::MakeN32(1, 1, kOpaque_SkAlphaType)); bitmap.eraseColor(SK_ColorRED); canvas->scale(16, 16); canvas->drawBitmap(bitmap, 0, 0); ## #SeeAlso eraseARGB erase ## # ------------------------------------------------------------------------------ #Method void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const #Line # writes Color to pixels ## Replaces pixel values with Unpremultiplied Color built from a, r, g, and b. All pixels contained by bounds() are affected. If the colorType is kGray_8_SkColorType or k565_SkColorType, then a is ignored; r, g, and b are treated as opaque. If colorType is kAlpha_8_SkColorType, then r, g, and b are ignored. #Param a amount of Color_Alpha, from fully transparent (0) to fully opaque (255) ## #Param r amount of Color_RGB_Red, from no red (0) to full red (255) ## #Param g amount of Color_RGB_Green, from no green (0) to full green (255) ## #Param b amount of Color_RGB_Blue, from no blue (0) to full blue (255) ## #Example #Height 80 SkBitmap bitmap; bitmap.allocPixels(SkImageInfo::MakeN32(1, 1, kPremul_SkAlphaType)); bitmap.eraseARGB(0x7f, 0xff, 0x7f, 0x3f); canvas->scale(50, 50); canvas->drawBitmap(bitmap, 0, 0); canvas->drawBitmap(bitmap, .5f, .5f); ## #SeeAlso eraseColor erase ## # ------------------------------------------------------------------------------ #Method void eraseRGB(U8CPU r, U8CPU g, U8CPU b) const #Line # deprecated ## Deprecated. Use eraseARGB or eraseColor. #Param r amount of red ## #Param g amount of green ## #Param b amount of blue ## #NoExample ## #SeeAlso eraseColor eraseARGB erase ## # ------------------------------------------------------------------------------ #Method void erase(SkColor c, const SkIRect& area) const #Line # writes Color to rectangle of pixels ## Replaces pixel values inside area with c. If area does not intersect bounds(), call has no effect. If the colorType is kGray_8_SkColorType or k565_SkColorType, then Color_Alpha is ignored; Color_RGB is treated as opaque. If colorType is kAlpha_8_SkColorType, then Color_RGB is ignored. #Param c Unpremultiplied Color ## #Param area rectangle to fill ## #Example #Height 70 SkBitmap bitmap; bitmap.allocPixels(SkImageInfo::MakeN32(2, 2, kPremul_SkAlphaType)); bitmap.erase(0x7fff7f3f, SkIRect::MakeWH(1, 1)); bitmap.erase(0x7f7f3fff, SkIRect::MakeXYWH(0, 1, 1, 1)); bitmap.erase(0x7f3fff7f, SkIRect::MakeXYWH(1, 0, 1, 1)); bitmap.erase(0x7f1fbf5f, SkIRect::MakeXYWH(1, 1, 1, 1)); canvas->scale(25, 25); canvas->drawBitmap(bitmap, 0, 0); canvas->drawBitmap(bitmap, .5f, .5f); ## #SeeAlso eraseColor eraseARGB eraseRGB SkCanvas::drawRect ## # ------------------------------------------------------------------------------ #Method void eraseArea(const SkIRect& area, SkColor c) const #Line # deprecated ## Legacy call to be deprecated. #Deprecated ## ## # ------------------------------------------------------------------------------ #Method SkColor getColor(int x, int y) const #Line # returns one pixel as Unpremultiplied Color ## Returns pixel at (x, y) as Unpremultiplied Color. Returns black with Alpha if Color_Type is kAlpha_8_SkColorType. Input is not validated: out of bounds values of x or y trigger an assert() if built with SK_DEBUG defined; and returns undefined values or may crash if SK_RELEASE is defined. Fails if Color_Type is kUnknown_SkColorType or pixel address is nullptr. Color_Space in Image_Info is ignored. Some Color precision may be lost in the conversion to Unpremultiplied Color; original pixel data may have additional precision. #Param x column index, zero or greater, and less than width() ## #Param y row index, zero or greater, and less than height() ## #Return pixel converted to Unpremultiplied Color ## #Example const int w = 4; const int h = 4; SkColor colors[][w] = { 0x00000000, 0x2a0e002a, 0x55380055, 0x7f7f007f, 0x2a000e2a, 0x551c1c55, 0x7f542a7f, 0xaaaa38aa, 0x55003855, 0x7f2a547f, 0xaa7171aa, 0xd4d48dd4, 0x7f007f7f, 0xaa38aaaa, 0xd48dd4d4, 0xffffffff, }; SkDebugf("Premultiplied:\n"); for (int y = 0; y < h; ++y) { SkDebugf("(0, %d) ", y); for (int x = 0; x < w; ++x) { SkDebugf("0x%08x%c", colors[y][x], x == w - 1 ? '\n' : ' '); } } SkPixmap pixmap(SkImageInfo::MakeN32(w, h, kPremul_SkAlphaType), colors, w * 4); SkBitmap bitmap; bitmap.installPixels(pixmap); SkDebugf("Unpremultiplied:\n"); for (int y = 0; y < h; ++y) { SkDebugf("(0, %d) ", y); for (int x = 0; x < w; ++x) { SkDebugf("0x%08x%c", bitmap.getColor(x, y), x == w - 1 ? '\n' : ' '); } } #StdOut Premultiplied: (0, 0) 0x00000000 0x2a0e002a 0x55380055 0x7f7f007f (0, 1) 0x2a000e2a 0x551c1c55 0x7f542a7f 0xaaaa38aa (0, 2) 0x55003855 0x7f2a547f 0xaa7171aa 0xd4d48dd4 (0, 3) 0x7f007f7f 0xaa38aaaa 0xd48dd4d4 0xffffffff Unpremultiplied: (0, 0) 0x00000000 0x2a5500ff 0x55a800ff 0x7fff00ff (0, 1) 0x2a0055ff 0x555454ff 0x7fa954ff 0xaaff54ff (0, 2) 0x5500a8ff 0x7f54a9ff 0xaaaaaaff 0xd4ffaaff (0, 3) 0x7f00ffff 0xaa54ffff 0xd4aaffff 0xffffffff ## ## #SeeAlso getAddr readPixels ## # ------------------------------------------------------------------------------ #Method void* getAddr(int x, int y) const #Line # returns readable pixel address as void pointer ## Returns pixel address at (x, y). Input is not validated: out of bounds values of x or y, or kUnknown_SkColorType, trigger an assert() if built with SK_DEBUG defined. Returns nullptr if Color_Type is kUnknown_SkColorType, or Pixel_Ref is nullptr. Performs a lookup of pixel size; for better performance, call one of: getAddr8, getAddr16, or getAddr32. #Param x column index, zero or greater, and less than width() ## #Param y row index, zero or greater, and less than height() ## #Return generic pointer to pixel ## #Example #Image 3 char* row0 = (char* ) source.getAddr(0, 0); char* row1 = (char* ) source.getAddr(0, 1); SkDebugf("addr interval %c= rowBytes\n", row1 - row0 == source.rowBytes() ? '=' : '!'); #StdOut addr interval == rowBytes ## ## #SeeAlso getAddr8 getAddr16 getAddr32 readPixels SkPixmap::addr ## # ------------------------------------------------------------------------------ #Method inline uint32_t* getAddr32(int x, int y) const #Line # returns readable pixel address as 32-bit pointer ## Returns address at (x, y). Input is not validated. Triggers an assert() if built with SK_DEBUG defined and: #List # Pixel_Ref is nullptr ## # bytesPerPixel() is not four ## # x is negative, or not less than width() ## # y is negative, or not less than height() ## ## #Param x column index, zero or greater, and less than width() ## #Param y row index, zero or greater, and less than height() ## #Return unsigned 32-bit pointer to pixel at (x, y) ## #Example #Image 3 uint32_t* row0 = source.getAddr32(0, 0); uint32_t* row1 = source.getAddr32(0, 1); size_t interval = (row1 - row0) * source.bytesPerPixel(); SkDebugf("addr interval %c= rowBytes\n", interval == source.rowBytes() ? '=' : '!'); #StdOut addr interval == rowBytes ## ## #SeeAlso getAddr8 getAddr16 getAddr readPixels SkPixmap::addr32 ## # ------------------------------------------------------------------------------ #Method inline uint16_t* getAddr16(int x, int y) const #Line # returns readable pixel address as 16-bit pointer ## Returns address at (x, y). Input is not validated. Triggers an assert() if built with SK_DEBUG defined and: #List # Pixel_Ref is nullptr ## # bytesPerPixel() is not two ## # x is negative, or not less than width() ## # y is negative, or not less than height() ## ## #Param x column index, zero or greater, and less than width() ## #Param y row index, zero or greater, and less than height() ## #Return unsigned 16-bit pointer to pixel at (x, y)## #Example #Image 3 SkBitmap bitmap16; SkImageInfo dstInfo = SkImageInfo::Make(source.width(), source.height(), kARGB_4444_SkColorType, kPremul_SkAlphaType); bitmap16.allocPixels(dstInfo); if (source.readPixels(dstInfo, bitmap16.getPixels(), bitmap16.rowBytes(), 0, 0)) { uint16_t* row0 = bitmap16.getAddr16(0, 0); uint16_t* row1 = bitmap16.getAddr16(0, 1); size_t interval = (row1 - row0) * bitmap16.bytesPerPixel(); SkDebugf("addr interval %c= rowBytes\n", interval == bitmap16.rowBytes() ? '=' : '!'); } #StdOut addr interval == rowBytes ## ## #SeeAlso getAddr8 getAddr getAddr32 readPixels SkPixmap::addr16 ## # ------------------------------------------------------------------------------ #Method inline uint8_t* getAddr8(int x, int y) const #Line # returns readable pixel address as 8-bit pointer ## Returns address at (x, y). Input is not validated. Triggers an assert() if built with SK_DEBUG defined and: #List # Pixel_Ref is nullptr ## # bytesPerPixel() is not one ## # x is negative, or not less than width() ## # y is negative, or not less than height() ## ## #Param x column index, zero or greater, and less than width() ## #Param y row index, zero or greater, and less than height() ## #Return unsigned 8-bit pointer to pixel at (x, y) ## #Example SkBitmap bitmap; const int width = 8; const int height = 8; uint8_t pixels[height][width]; SkImageInfo info = SkImageInfo::Make(width, height, kGray_8_SkColorType, kOpaque_SkAlphaType); if (bitmap.installPixels(info, pixels, info.minRowBytes())) { SkDebugf("&pixels[4][2] %c= bitmap.getAddr8(2, 4)\n", &pixels[4][2] == bitmap.getAddr8(2, 4) ? '=' : '!'); } #StdOut &pixels[4][2] == bitmap.getAddr8(2, 4) ## ## #SeeAlso getAddr getAddr16 getAddr32 readPixels SkPixmap::addr8 ## # ------------------------------------------------------------------------------ #Method bool extractSubset(SkBitmap* dst, const SkIRect& subset) const #Line # creates Bitmap, sharing pixels if possible ## Shares Pixel_Ref with dst. Pixels are not copied; Bitmap and dst point to the same pixels; dst bounds() are set to the intersection of subset and the original bounds(). subset may be larger than bounds(). Any area outside of bounds() is ignored. Any contents of dst are discarded. isVolatile setting is copied to dst. dst is set to colorType, alphaType, and colorSpace. Return false if: #List # dst is nullptr ## # Pixel_Ref is nullptr ## # subset does not intersect bounds() ## ## #Param dst Bitmap set to subset ## #Param subset rectangle of pixels to reference ## #Return true if dst is replaced by subset ## #Example #Image 3 SkIRect bounds, s; source.getBounds(&bounds); SkDebugf("bounds: %d, %d, %d, %d\n", bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom); SkBitmap subset; for (int left: { -100, 0, 100, 1000 } ) { for (int right: { 0, 100, 1000 } ) { SkIRect b = SkIRect::MakeLTRB(left, 100, right, 200); bool success = source.extractSubset(&subset, b); SkDebugf("subset: %4d, %4d, %4d, %4d ", b.fLeft, b.fTop, b.fRight, b.fBottom); SkDebugf("success; %s", success ? "true" : "false"); if (success) { subset.getBounds(&s); SkDebugf(" subset: %d, %d, %d, %d", s.fLeft, s.fTop, s.fRight, s.fBottom); } SkDebugf("\n"); } } #StdOut bounds: 0, 0, 512, 512 subset: -100, 100, 0, 200 success; false subset: -100, 100, 100, 200 success; true subset: 0, 0, 100, 100 subset: -100, 100, 1000, 200 success; true subset: 0, 0, 512, 100 subset: 0, 100, 0, 200 success; false subset: 0, 100, 100, 200 success; true subset: 0, 0, 100, 100 subset: 0, 100, 1000, 200 success; true subset: 0, 0, 512, 100 subset: 100, 100, 0, 200 success; false subset: 100, 100, 100, 200 success; false subset: 100, 100, 1000, 200 success; true subset: 0, 0, 412, 100 subset: 1000, 100, 0, 200 success; false subset: 1000, 100, 100, 200 success; false subset: 1000, 100, 1000, 200 success; false ## ## #SeeAlso readPixels writePixels SkCanvas::drawBitmap ## # ------------------------------------------------------------------------------ #Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, int srcX, int srcY, SkTransferFunctionBehavior behavior) const #Line # copies and converts pixels ## Copies Rect of pixels from Bitmap pixels to dstPixels. Copy starts at (srcX, srcY), and does not exceed Bitmap (width(), height()). dstInfo specifies width, height, Color_Type, Alpha_Type, and Color_Space of destination. dstRowBytes specifics the gap from one destination row to the next. Returns true if pixels are copied. Returns false if: #List # dstInfo.addr() equals nullptr ## # dstRowBytes is less than dstInfo.minRowBytes ## # Pixel_Ref is nullptr ## ## Pixels are copied only if pixel conversion is possible. If Bitmap colorType is kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType must match. If Bitmap colorType is kGray_8_SkColorType, dstInfo.colorSpace must match. If Bitmap alphaType is kOpaque_SkAlphaType, dstInfo.alphaType must match. If Bitmap colorSpace is nullptr, dstInfo.colorSpace must match. Returns false if pixel conversion is not possible. srcX and srcY may be negative to copy only top or left of source. Returns false if width() or height() is zero or negative. Returns false if #Formula abs(srcX) >= Bitmap width() ## , or if #Formula abs(srcY) >= Bitmap height() ## . If behavior is SkTransferFunctionBehavior::kRespect: converts source pixels to a linear space before converting to dstInfo. If behavior is SkTransferFunctionBehavior::kIgnore: source pixels are treated as if they are linear, regardless of how they are encoded. #Param dstInfo destination width, height, Color_Type, Alpha_Type, Color_Space ## #Param dstPixels destination pixel storage ## #Param dstRowBytes destination row length ## #Param srcX column index whose absolute value is less than width() ## #Param srcY row index whose absolute value is less than height() ## #Param behavior one of: SkTransferFunctionBehavior::kRespect, SkTransferFunctionBehavior::kIgnore ## #Return true if pixels are copied to dstPixels ## #Example #Height 64 void draw(SkCanvas* canvas) { const int width = 256; const int height = 32; std::vector<int32_t> dstPixels; dstPixels.resize(height * width * 4); SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); SkColor gradColors[] = { 0xFFAA3300, 0x7F881122 }; SkPoint gradPoints[] = { { 0, 0 }, { width, 0 } }; SkPaint gradPaint; gradPaint.setShader(SkGradientShader::MakeLinear(gradPoints, gradColors, nullptr, SK_ARRAY_COUNT(gradColors), SkShader::kClamp_TileMode)); for (auto behavior : { SkTransferFunctionBehavior::kRespect, SkTransferFunctionBehavior::kIgnore} ) { SkBitmap bitmap; bitmap.allocPixels(info); SkCanvas srcCanvas(bitmap); srcCanvas.drawRect(SkRect::MakeWH(width, height), gradPaint); if (bitmap.readPixels(info, &dstPixels.front(), width * 4, 0, 0, behavior)) { SkPixmap dstPixmap(info, &dstPixels.front(), width * 4); bitmap.installPixels(dstPixmap); canvas->drawBitmap(bitmap, 0, 0); } canvas->translate(0, height); } } ## #SeeAlso writePixels SkPixmap::readPixels SkCanvas::readPixels SkImage::readPixels SkSurface::readPixels ## # ------------------------------------------------------------------------------ #Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, int srcX, int srcY) const Copies a Rect of pixels from Bitmap to dstPixels. Copy starts at (srcX, srcY), and does not exceed Bitmap (width(), height()). dstInfo specifies width, height, Color_Type, Alpha_Type, and Color_Space of destination. dstRowBytes specifics the gap from one destination row to the next. Returns true if pixels are copied. Returns false if: #List # dstInfo.addr() equals nullptr ## # dstRowBytes is less than dstInfo.minRowBytes ## # Pixel_Ref is nullptr ## ## Pixels are copied only if pixel conversion is possible. If Bitmap colorType is kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType must match. If Bitmap colorType is kGray_8_SkColorType, dstInfo.colorSpace must match. If Bitmap alphaType is kOpaque_SkAlphaType, dstInfo.alphaType must match. If Bitmap colorSpace is nullptr, dstInfo.colorSpace must match. Returns false if pixel conversion is not possible. srcX and srcY may be negative to copy only top or left of source. Returns false if width() or height() is zero or negative. Returns false if #Formula abs(srcX) >= Bitmap width() ## , or if #Formula abs(srcY) >= Bitmap height() ## . #Param dstInfo destination width, height, Color_Type, Alpha_Type, Color_Space ## #Param dstPixels destination pixel storage ## #Param dstRowBytes destination row length ## #Param srcX column index whose absolute value is less than width() ## #Param srcY row index whose absolute value is less than height() ## #Return true if pixels are copied to dstPixels ## #Example #Height 128 #Description Transferring the gradient from 8 bits per component to 4 bits per component creates visible banding. ## const int width = 256; const int height = 64; SkImageInfo srcInfo = SkImageInfo::MakeN32Premul(width, height); SkColor gradColors[] = { 0xFFAA3300, 0x7F881122 }; SkPoint gradPoints[] = { { 0, 0 }, { 256, 0 } }; SkPaint paint; paint.setShader(SkGradientShader::MakeLinear(gradPoints, gradColors, nullptr, SK_ARRAY_COUNT(gradColors), SkShader::kClamp_TileMode)); SkBitmap bitmap; bitmap.allocPixels(srcInfo); SkCanvas srcCanvas(bitmap); srcCanvas.drawRect(SkRect::MakeWH(width, height), paint); canvas->drawBitmap(bitmap, 0, 0); SkImageInfo dstInfo = srcInfo.makeColorType(kARGB_4444_SkColorType); std::vector<int16_t> dstPixels; dstPixels.resize(height * width); bitmap.readPixels(dstInfo, &dstPixels.front(), width * 2, 0, 0); SkPixmap dstPixmap(dstInfo, &dstPixels.front(), width * 2); bitmap.installPixels(dstPixmap); canvas->drawBitmap(bitmap, 0, 64); ## #SeeAlso writePixels SkPixmap::readPixels SkCanvas::readPixels SkImage::readPixels SkSurface::readPixels ## # ------------------------------------------------------------------------------ #Method bool readPixels(const SkPixmap& dst, int srcX, int srcY) const Copies a Rect of pixels from Bitmap to dst. Copy starts at (srcX, srcY), and does not exceed Bitmap (width(), height()). dst specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage, and row bytes of destination. dst.rowBytes specifics the gap from one destination row to the next. Returns true if pixels are copied. Returns false if: #List # dst pixel storage equals nullptr ## # dst.rowBytes is less than SkImageInfo::minRowBytes ## # Pixel_Ref is nullptr ## ## Pixels are copied only if pixel conversion is possible. If Bitmap colorType is kGray_8_SkColorType, or kAlpha_8_SkColorType; dst Color_Type must match. If Bitmap colorType is kGray_8_SkColorType, dst Color_Space must match. If Bitmap alphaType is kOpaque_SkAlphaType, dst Alpha_Type must match. If Bitmap colorSpace is nullptr, dst Color_Space must match. Returns false if pixel conversion is not possible. srcX and srcY may be negative to copy only top or left of source. Returns false if width() or height() is zero or negative. Returns false if #Formula abs(srcX) >= Bitmap width() ## , or if #Formula abs(srcY) >= Bitmap height() ## . #Param dst destination Pixmap: Image_Info, pixels, row bytes ## #Param srcX column index whose absolute value is less than width() ## #Param srcY row index whose absolute value is less than height() ## #Return true if pixels are copied to dst ## #Example #Image 3 std::vector<int32_t> srcPixels; srcPixels.resize(source.height() * source.rowBytes()); for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { SkPixmap pixmap(SkImageInfo::MakeN32Premul(source.width() / 4, source.height() / 4), &srcPixels.front() + x * source.height() * source.width() / 4 + y * source.width() / 4, source.rowBytes()); source.readPixels(pixmap, x * source.width() / 4, y * source.height() / 4); } } canvas->scale(.5f, .5f); SkBitmap bitmap; bitmap.installPixels(SkImageInfo::MakeN32Premul(source.width(), source.height()), &srcPixels.front(), source.rowBytes()); canvas->drawBitmap(bitmap, 0, 0); ## #SeeAlso writePixels SkPixmap::readPixels SkCanvas::readPixels SkImage::readPixels SkSurface::readPixels ## # ------------------------------------------------------------------------------ #Method bool readPixels(const SkPixmap& dst) const Copies a Rect of pixels from Bitmap to dst. Copy starts at (0, 0), and does not exceed Bitmap (width(), height()). dst specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage, and row bytes of destination. dst.rowBytes specifics the gap from one destination row to the next. Returns true if pixels are copied. Returns false if: #List # dst pixel storage equals nullptr ## # dst.rowBytes is less than SkImageInfo::minRowBytes ## # Pixel_Ref is nullptr ## ## Pixels are copied only if pixel conversion is possible. If Bitmap colorType is kGray_8_SkColorType, or kAlpha_8_SkColorType; dst Color_Type must match. If Bitmap colorType is kGray_8_SkColorType, dst Color_Space must match. If Bitmap alphaType is kOpaque_SkAlphaType, dst Alpha_Type must match. If Bitmap colorSpace is nullptr, dst Color_Space must match. Returns false if pixel conversion is not possible. #Param dst destination Pixmap: Image_Info, pixels, row bytes ## #Return true if pixels are copied to dst ## #Example #Height 128 #Image 3 std::vector<int32_t> srcPixels; srcPixels.resize(source.height() * source.width() * 8); for (int i = 0; i < 2; ++i) { SkPixmap pixmap(SkImageInfo::Make(source.width() * 2, source.height(), i ? kRGBA_8888_SkColorType : kBGRA_8888_SkColorType, kPremul_SkAlphaType), &srcPixels.front() + i * source.width(), source.rowBytes() * 2); source.readPixels(pixmap); } canvas->scale(.25f, .25f); SkBitmap bitmap; bitmap.installPixels(SkImageInfo::MakeN32Premul(source.width() * 2, source.height()), &srcPixels.front(), source.rowBytes() * 2); canvas->drawBitmap(bitmap, 0, 0); ## #SeeAlso writePixels SkPixmap::readPixels SkCanvas::readPixels SkImage::readPixels SkSurface::readPixels ## # ------------------------------------------------------------------------------ #Method bool writePixels(const SkPixmap& src, int dstX, int dstY) #Line # copies and converts pixels ## Copies a Rect of pixels from src. Copy starts at (dstX, dstY), and does not exceed (src.width(), src.height()). src specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage, and row bytes of source. src.rowBytes specifics the gap from one source row to the next. Returns true if pixels are copied. Returns false if: #List # src pixel storage equals nullptr ## # src.rowBytes is less than SkImageInfo::minRowBytes ## # Pixel_Ref is nullptr ## ## Pixels are copied only if pixel conversion is possible. If Bitmap colorType is kGray_8_SkColorType, or kAlpha_8_SkColorType; src Color_Type must match. If Bitmap colorType is kGray_8_SkColorType, src Color_Space must match. If Bitmap alphaType is kOpaque_SkAlphaType, src Alpha_Type must match. If Bitmap colorSpace is nullptr, src Color_Space must match. Returns false if pixel conversion is not possible. dstX and dstY may be negative to copy only top or left of source. Returns false if width() or height() is zero or negative. Returns false if #Formula abs(dstX) >= Bitmap width() ## , or if #Formula abs(dstY) >= Bitmap height() ## . #Param src source Pixmap: Image_Info, pixels, row bytes ## #Param dstX column index whose absolute value is less than width() ## #Param dstY row index whose absolute value is less than height() ## #Return true if src pixels are copied to Bitmap ## #Example #Image 3 std::vector<int32_t> srcPixels; int width = image->width(); int height = image->height(); srcPixels.resize(height * width * 4); SkPixmap pixmap(SkImageInfo::MakeN32Premul(width, height), (const void*) &srcPixels.front(), width * 4); image->readPixels(pixmap, 0, 0); canvas->scale(.5f, .5f); width /= 4; height /= 4; for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { SkBitmap bitmap; bitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height)); bitmap.writePixels(pixmap, -y * width, -x * height); canvas->drawBitmap(bitmap, x * width, y * height); } } ## #SeeAlso readPixels ## # ------------------------------------------------------------------------------ #Method bool writePixels(const SkPixmap& src) Copies a Rect of pixels from src. Copy starts at (0, 0), and does not exceed (src.width(), src.height()). src specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage, and row bytes of source. src.rowBytes specifics the gap from one source row to the next. Returns true if pixels are copied. Returns false if: #List # src pixel storage equals nullptr ## # src.rowBytes is less than SkImageInfo::minRowBytes ## # Pixel_Ref is nullptr ## ## Pixels are copied only if pixel conversion is possible. If Bitmap colorType is kGray_8_SkColorType, or kAlpha_8_SkColorType; src Color_Type must match. If Bitmap colorType is kGray_8_SkColorType, src Color_Space must match. If Bitmap alphaType is kOpaque_SkAlphaType, src Alpha_Type must match. If Bitmap colorSpace is nullptr, src Color_Space must match. Returns false if pixel conversion is not possible. #Param src source Pixmap: Image_Info, pixels, row bytes ## #Return true if src pixels are copied to Bitmap ## #Example #Height 80 SkBitmap bitmap; bitmap.allocPixels(SkImageInfo::MakeN32Premul(2, 2)); bitmap.eraseColor(SK_ColorGREEN); SkPMColor color = 0xFF5599BB; SkPixmap src(SkImageInfo::MakeN32Premul(1, 1), &color, 4); bitmap.writePixels(src); canvas->scale(40, 40); canvas->drawBitmap(bitmap, 0, 0); ## #SeeAlso readPixels ## # ------------------------------------------------------------------------------ #Method bool writePixels(const SkPixmap& src, int x, int y, SkTransferFunctionBehavior behavior) Copies a Rect of pixels from src. Copy starts at (0, 0), and does not exceed (src.width(), src.height()). src specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage, and row bytes of source. src.rowBytes specifics the gap from one source row to the next. Returns true if pixels are copied. Returns false if: #List # src pixel storage equals nullptr ## # src.rowBytes is less than SkImageInfo::minRowBytes ## # Pixel_Ref is nullptr ## ## Pixels are copied only if pixel conversion is possible. If Bitmap colorType is kGray_8_SkColorType, or kAlpha_8_SkColorType; src Color_Type must match. If Bitmap colorType is kGray_8_SkColorType, src Color_Space must match. If Bitmap alphaType is kOpaque_SkAlphaType, src Alpha_Type must match. If Bitmap colorSpace is nullptr, src Color_Space must match. Returns false if pixel conversion is not possible. Returns false if width() or height() is zero or negative. If behavior is SkTransferFunctionBehavior::kRespect: converts src pixels to a linear space before converting to Image_Info. If behavior is SkTransferFunctionBehavior::kIgnore: src pixels are treated as if they are linear, regardless of how they are encoded. #Param src source Pixmap: Image_Info, pixels, row bytes ## #Param x column index whose absolute value is less than width() ## #Param y row index whose absolute value is less than height() ## #Param behavior one of: SkTransferFunctionBehavior::kRespect, SkTransferFunctionBehavior::kIgnore ## #Return true if src pixels are copied to Bitmap ## #Example #Height 64 const int width = 256; const int height = 32; std::vector<int32_t> dstPixels; dstPixels.resize(height * width * 4); SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); SkColor gradColors[] = { 0xFFAA3300, 0x7F881122 }; SkPoint gradPoints[] = { { 0, 0 }, { width, 0 } }; SkPaint gradPaint; gradPaint.setShader(SkGradientShader::MakeLinear(gradPoints, gradColors, nullptr, SK_ARRAY_COUNT(gradColors), SkShader::kClamp_TileMode)); for (auto behavior : { SkTransferFunctionBehavior::kRespect, SkTransferFunctionBehavior::kIgnore} ) { SkPixmap dstPixmap(info, &dstPixels.front(), width * 4); SkBitmap bitmap; bitmap.installPixels(dstPixmap); SkCanvas srcCanvas(bitmap); srcCanvas.drawRect(SkRect::MakeWH(width, height), gradPaint); if (bitmap.writePixels(dstPixmap, 0, 0, behavior)) { canvas->drawBitmap(bitmap, 0, 0); } canvas->translate(0, height); } ## #SeeAlso readPixels ## # ------------------------------------------------------------------------------ #Method bool hasHardwareMipMap() const #Line # returns Mip_Map support present; Android only ## #Private Android framework only. ## #Return true if setHasHardwareMipMap has been called with true ## #NoExample ## #SeeAlso setHasHardwareMipMap ## # ------------------------------------------------------------------------------ #Method void setHasHardwareMipMap(bool hasHardwareMipMap) #Line # sets Mip_Map support present; Android only ## #Private Android framework only. ## #Param hasHardwareMipMap sets state ## #NoExample ## #SeeAlso hasHardwareMipMap ## # ------------------------------------------------------------------------------ #Method bool extractAlpha(SkBitmap* dst) const #Line # creates Bitmap containing Alpha of pixels ## Sets dst to Alpha described by pixels. Returns false if dst cannot be written to or dst pixels cannot be allocated. Uses HeapAllocator to reserve memory for dst Pixel_Ref. #Param dst holds Pixel_Ref to fill with alpha layer ## #Return true if Alpha layer was constructed in dst Pixel_Ref ## #Example #Height 100 SkBitmap alpha, bitmap; bitmap.allocN32Pixels(100, 100); SkCanvas offscreen(bitmap); offscreen.clear(0); SkPaint paint; paint.setAntiAlias(true); paint.setColor(SK_ColorBLUE); paint.setStyle(SkPaint::kStroke_Style); paint.setStrokeWidth(20); offscreen.drawCircle(50, 50, 39, paint); offscreen.flush(); bitmap.extractAlpha(&alpha); paint.setColor(SK_ColorRED); canvas->drawBitmap(bitmap, 0, 0, &paint); canvas->drawBitmap(alpha, 100, 0, &paint); ## #SeeAlso extractSubset ## # ------------------------------------------------------------------------------ #Method bool extractAlpha(SkBitmap* dst, const SkPaint* paint, SkIPoint* offset) const Sets dst to Alpha described by pixels. Returns false if dst cannot be written to or dst pixels cannot be allocated. If paint is not nullptr and contains Mask_Filter, SkMaskFilter::filterMask generates Mask_Alpha from Bitmap. Uses HeapAllocator to reserve memory for dst Pixel_Ref. Sets offset to top-left position for dst for alignment with Bitmap; (0, 0) unless SkMaskFilter generates mask. #Param dst holds Pixel_Ref to fill with alpha layer ## #Param paint holds optional Mask_Filter; may be nullptr ## #Param offset top-left position for dst; may be nullptr ## #Return true if Alpha layer was constructed in dst Pixel_Ref ## #Bug 7103 ## #Example #Height 160 SkBitmap alpha, bitmap; bitmap.allocN32Pixels(100, 100); SkCanvas offscreen(bitmap); offscreen.clear(0); SkPaint paint; paint.setAntiAlias(true); paint.setColor(SK_ColorBLUE); paint.setStyle(SkPaint::kStroke_Style); paint.setStrokeWidth(20); offscreen.drawCircle(50, 50, 39, paint); offscreen.flush(); const SkScalar kBlurSigma = SkBlurMaskFilter::ConvertRadiusToSigma(SkIntToScalar(25)); paint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, kBlurSigma, SkBlurMaskFilter::kHighQuality_BlurFlag)); SkIPoint offset; bitmap.extractAlpha(&alpha, &paint, &offset); paint.setColor(SK_ColorRED); canvas->drawBitmap(bitmap, 0, -offset.fY, &paint); canvas->drawBitmap(alpha, 100 + offset.fX, 0, &paint); ## #SeeAlso extractSubset ## # ------------------------------------------------------------------------------ #Method bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator, SkIPoint* offset) const Sets dst to Alpha described by pixels. Returns false if dst cannot be written to or dst pixels cannot be allocated. If paint is not nullptr and contains Mask_Filter, SkMaskFilter::filterMask generates Mask_Alpha from Bitmap. allocator may reference a custom allocation class or be set to nullptr to use HeapAllocator. Sets offset to top-left position for dst for alignment with Bitmap; (0, 0) unless SkMaskFilter generates mask. #Param dst holds Pixel_Ref to fill with alpha layer ## #Param paint holds optional Mask_Filter; may be nullptr ## #Param allocator method to reserve memory for Pixel_Ref; may be nullptr ## #Param offset top-left position for dst; may be nullptr ## #Return true if Alpha layer was constructed in dst Pixel_Ref ## #Bug 7104 ## #Example #Height 128 SkBitmap alpha, bitmap; bitmap.allocN32Pixels(100, 100); SkCanvas offscreen(bitmap); offscreen.clear(0); SkPaint paint; paint.setAntiAlias(true); paint.setColor(SK_ColorBLUE); paint.setStyle(SkPaint::kStroke_Style); paint.setStrokeWidth(20); offscreen.drawCircle(50, 50, 39, paint); offscreen.flush(); paint.setMaskFilter(SkBlurMaskFilter::Make(kOuter_SkBlurStyle, 3)); SkIPoint offset; bitmap.extractAlpha(&alpha, &paint, nullptr, &offset); paint.setColor(SK_ColorRED); canvas->drawBitmap(bitmap, 0, -offset.fY, &paint); canvas->drawBitmap(alpha, 100 + offset.fX, 0, &paint); ## #SeeAlso extractSubset ## # ------------------------------------------------------------------------------ #Method bool peekPixels(SkPixmap* pixmap) const #Line # returns Pixmap if possible ## Copies Bitmap pixel address, row bytes, and Image_Info to pixmap, if address is available, and returns true. If pixel address is not available, return false and leave pixmap unchanged. pixmap contents become invalid on any future change to Bitmap. #Param pixmap storage for pixel state if pixels are readable; otherwise, ignored ## #Return true if Bitmap has direct access to pixels ## #Example SkBitmap bitmap; bitmap.allocPixels(SkImageInfo::MakeN32Premul(6, 11)); SkCanvas offscreen(bitmap); offscreen.clear(SK_ColorWHITE); SkPaint paint; offscreen.drawString("?", 0, 10, paint); SkPixmap pixmap; if (bitmap.peekPixels(&pixmap)) { const SkPMColor* pixels = pixmap.addr32(); SkPMColor pmWhite = pixels[0]; for (int y = 0; y < bitmap.height(); ++y) { for (int x = 0; x < bitmap.width(); ++x) { SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x'); } SkDebugf("\n"); } } #StdOut ------ -xxx-- x---x- ----x- ---x-- --x--- --x--- ------ --x--- --x--- ------ #StdOut ## ## #SeeAlso pixmap() installPixels readPixels writePixels ## # ------------------------------------------------------------------------------ #Method void validate() const; #Line # asserts if Bitmap is invalid (debug only) ## Asserts if internal values are illegal or inconsistent. Only available if SK_DEBUG is defined at compile time. #NoExample ## #SeeAlso SkImageInfo::validate() ## # ------------------------------------------------------------------------------ #Method void toString(SkString* str) const; #Line # converts Bitmap to machine readable form ## #DefinedBy SK_TO_STRING_NONVIRT() ## #Private macro expands to: void toString(SkString* str) const; ## Creates string representation of Bitmap. The representation is read by internal debugging tools. The interface and implementation may be suppressed by defining SK_IGNORE_TO_STRING. #Param str storage for string representation ## #Example SkBitmap bitmap; int width = 6; int height = 11; bitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height)); SkString string; bitmap.toString(&string); SkString match; match.printf("(%d, %d)", width, height); int start = string.find(match.c_str()); if (start >= 0) { SkString whStr(&string.c_str()[start], match.size()); SkDebugf("bitmap dimensions %s\n", whStr.c_str()); } #StdOut bitmap dimensions (6, 11) ## ## #SeeAlso SkPaint::toString ## #Class SkBitmap ## #Topic Bitmap ##