blob: 1a943ad326ff070b5e240c78eacaf24e1422642d [file] [log] [blame]
#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(&copy, {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(&copy, {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 ##