blob: f0b50f9f88f5973ed6141794ede6fddef3c4a911 [file] [log] [blame]
#Topic Bitmap
#Alias Bitmaps ##
#Alias Bitmap_Reference ##
#Class SkBitmap
#Line # two-dimensional raster pixel array ##
#Code
#Populate
##
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 member functions. 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.
##
# ------------------------------------------------------------------------------
#Class Allocator
#Line # abstract subclass of HeapAllocator ##
#Code
#Populate
##
Abstract subclass of HeapAllocator.
# ------------------------------------------------------------------------------
#Method virtual bool allocPixelRef(SkBitmap* bitmap) = 0
#Line # allocates pixel memory ##
#Populate
#NoExample
##
#SeeAlso HeapAllocator
##
#Class Allocator ##
# ------------------------------------------------------------------------------
#Class HeapAllocator
#Line # allocates pixel memory from heap ##
#Code
#Populate
##
Subclass of SkBitmap::Allocator that returns a Pixel_Ref that allocates its pixel
memory from the heap. This is the default SkBitmap::Allocator invoked by
allocPixels.
# ------------------------------------------------------------------------------
#Method bool allocPixelRef(SkBitmap* bitmap) override
#Line # allocates pixel memory ##
#Populate
#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 SkBitmap::Allocator tryAllocPixels
##
#Class HeapAllocator ##
# ------------------------------------------------------------------------------
#Method SkBitmap()
#Line # constructs with default values ##
#Populate
#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 ##
#Populate
#Example
void draw(SkCanvas* canvas) {
SkBitmap original;
if (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 ##
#Populate
#Example
void draw(SkCanvas* canvas) {
SkBitmap original;
if (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 ##
#Populate
#NoExample
##
#SeeAlso Pixel_Ref
##
# ------------------------------------------------------------------------------
#Method SkBitmap& operator=(const SkBitmap& src)
#Line # shares ownership of pixels ##
#Populate
#Example
void draw(SkCanvas* canvas) {
SkBitmap original;
if (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 ##
#Populate
#Example
void draw(SkCanvas* canvas) {
SkBitmap original;
if (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)
#In Utility
#Line # exchanges Bitmap pair ##
#Populate
#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;
if (!one.tryAllocPixels(
SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType))) {
return;
}
if (!two.tryAllocPixels(
SkImageInfo::Make(2, 2, kBGRA_8888_SkColorType, kPremul_SkAlphaType))) {
return;
}
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)
##
# ------------------------------------------------------------------------------
#Subtopic Property
#Line # metrics and attributes ##
##
#Method const SkPixmap& pixmap() const
#In Property
#Line # returns Pixmap ##
#Populate
#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
#In Property
#Line # returns Image_Info ##
#Populate
#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
#In Property
#Line # returns pixel column count ##
Returns pixel count in each row. Should be equal or less than
#Formula # rowBytes() / info().bytesPerPixel() ##.
May 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
#In Property
#Line # returns pixel row count ##
#Populate
#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
#In Property
#Line # returns Image_Info Color_Type ##
Returns Color_Type, one of: #list_of_color_types#.
#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
#In Property
#Line # returns Image_Info Alpha_Type ##
Returns Alpha_Type, one of: #list_of_alpha_types#.
#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
#In Property
#Line # returns Image_Info Color_Space ##
#Populate
#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
#In Property
#Line # returns Image_Info Color_Space ##
#Populate
#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
#In Property
#Line # returns number of bytes in pixel based on Color_Type ##
#Populate
#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 : { #list_of_color_types#
} ) {
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: kRGB_888x_SkColorType bytesPerPixel: 4
color: kBGRA_8888_SkColorType bytesPerPixel: 4
color: kRGBA_1010102_SkColorType bytesPerPixel: 4
color: kRGB_101010x_SkColorType bytesPerPixel: 4
color: kGray_8_SkColorType bytesPerPixel: 1
color: kRGBA_F16_SkColorType bytesPerPixel: 8
##
##
#SeeAlso rowBytes rowBytesAsPixels width shiftPerPixel SkImageInfo::bytesPerPixel
##
# ------------------------------------------------------------------------------
#Method int rowBytesAsPixels() const
#In Property
#Line # returns interval between rows in pixels ##
#Populate
#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
#In Property
#Line # returns bit shift from pixels to bytes ##
#Populate
#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 : { #list_of_color_types#
} ) {
bitmap.setInfo(info.makeColorType(colorType));
SkDebugf("color: k" "%s" "_SkColorType" "%*s" "shiftPerPixel: %d\n",
colors[colorType], 14 - 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: kRGB_888x_SkColorType shiftPerPixel: 2
color: kBGRA_8888_SkColorType shiftPerPixel: 2
color: kRGBA_1010102_SkColorType shiftPerPixel: 2
color: kRGB_101010x_SkColorType shiftPerPixel: 2
color: kGray_8_SkColorType shiftPerPixel: 0
color: kRGBA_F16_SkColorType shiftPerPixel: 3
##
##
#SeeAlso rowBytes rowBytesAsPixels width bytesPerPixel
##
# ------------------------------------------------------------------------------
#Method bool empty() const
#In Property
#Line # returns true if Image_Info has zero width() or height() ##
#Populate
#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
#In Property
#Line # returns true if Pixel_Ref is nullptr ##
#Populate
#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
#In Property
#Line # returns true if no width(), no height(), or no Pixel_Ref ##
#Populate
#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
#In Property
#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)
#In Set
#Line # sets Alpha_Type of shared pixels ##
#Populate
#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[] = { #list_of_alpha_types#
};
SkDebugf("%18s%15s%17s%18s%19s\n", "Canonical", "Unknown", "Opaque", "Premul", "Unpremul");
for (SkColorType colorType : { #list_of_color_types#
} ) {
for (SkAlphaType canonicalAlphaType : alphaTypes) {
SkColorTypeValidateAlphaType(colorType, kUnknown_SkAlphaType, &canonicalAlphaType );
SkDebugf("%12s %9s ", 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
#In Property
#Line # returns address of pixels ##
#Populate
#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
#In Utility
#Line # returns size required for pixels ##
#Populate
#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
#In Property
#Line # returns true if pixels will not change ##
#Populate
#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()
#In Set
#Line # marks that pixels will not change ##
#Populate
#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
#In Property
#Line # returns true if Image_Info describes opaque pixels ##
#Populate
#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
#In Property
#Line # returns true if pixels should not be cached ##
#Populate
#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)
#In Set
#Line # marks if pixels should not be cached ##
#Populate
#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()
#In Constructors
#Line # sets to default values, releases pixel ownership ##
#Populate
#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)
#In Utility
#Line # returns true if all pixels are opaque ##
#Populate
#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
#In Property
#Line # returns width() and height() as Rectangle ##
#Populate
#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
#Populate
#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
#In Property
#Line # returns width() and height() as Rectangle ##
#Populate
#Example
#Height 64
#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
#In Property
#Line # returns width() and height() ##
#Populate
#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
#In Property
#Line # returns bounds offset by origin ##
#Populate
#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)
#In Set
#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
#Line # zero pixel memory ##
#Code
#Populate
##
AllocFlags provides the option to zero pixel memory when allocated.
#Const kZeroPixels_AllocFlag 1
#Line # zero pixel memory ##
Instructs tryAllocPixelsFlags and allocPixelsFlags to zero pixel memory.
##
#NoExample
##
#SeeAlso tryAllocPixelsFlags allocPixelsFlags erase eraseColor
##
# ------------------------------------------------------------------------------
#Subtopic Allocate
#Line # allocates storage for pixels ##
##
#Method bool tryAllocPixelsFlags(const SkImageInfo& info, uint32_t flags)
#In Allocate
#Line # allocates pixels from Image_Info with options if possible ##
#Populate
#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)
#In Allocate
#Line # allocates pixels from Image_Info with options, or aborts ##
#Populate
#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 tryAllocPixels(const SkImageInfo& info, size_t rowBytes)
#In Allocate
#Line # allocates pixels from Image_Info if possible ##
#Populate
#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)
#In Allocate
#Line # allocates pixels from Image_Info, or aborts ##
#Populate
#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 tryAllocPixels(const SkImageInfo& info)
#Populate
#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)
#Populate
#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 tryAllocN32Pixels(int width, int height, bool isOpaque = false)
#In Allocate
#Line # allocates compatible ARGB pixels if possible ##
#Populate
#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)
#In Allocate
#Line # allocates compatible ARGB pixels, or aborts ##
#Populate
#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)
#In Allocate
#Line # creates Pixel_Ref, with optional release function ##
#Populate
#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)
#Populate
#Example
#Bug 7079
#Description
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)
#Populate
#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
##
# ------------------------------------------------------------------------------
#Subtopic Pixels
#Line # read and write pixel values ##
##
#Method void setPixels(void* pixels)
#In Pixels
#Line # sets Pixel_Ref without an offset ##
#Populate
#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 tryAllocPixels()
#In Allocate
#Populate
#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()
#In Allocate
#Populate
#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 tryAllocPixels(Allocator* allocator)
#Populate
#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)
#Populate
#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
#In Property
#Line # returns Pixel_Ref, or nullptr ##
#Populate
#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
#In Property
#Line # returns offset within Pixel_Ref ##
#Populate
#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
##
# ------------------------------------------------------------------------------
#Subtopic Set
#Line # updates values and attributes ##
##
#Method void setPixelRef(sk_sp<SkPixelRef> pixelRef, int dx, int dy)
#In Set
#Line # sets Pixel_Ref and offset ##
#Populate
#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
#In Utility
#Line # returns true if address of pixels is not nullptr ##
#Populate
#Example
#Image 5
#Height 160
if (source.readyToDraw()) {
canvas->drawBitmap(source, 10, 10);
}
##
#SeeAlso getPixels drawsNothing
##
# ------------------------------------------------------------------------------
#Method uint32_t getGenerationID() const
#In Utility
#Line # returns unique ID ##
#Populate
#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
#In Pixels
#Line # marks pixels as changed, altering the unique ID ##
#Populate
#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
##
# ------------------------------------------------------------------------------
#Subtopic Draw
#Line # sets pixels to Color ##
##
#Method void eraseColor(SkColor c) const
#In Draw
#Line # writes Color to pixels ##
#Populate
#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
#In Draw
#Line # writes Color to pixels ##
#Populate
#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 erase(SkColor c, const SkIRect& area) const
#In Draw
#Line # writes Color to rectangle of pixels ##
#Populate
#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 SkCanvas::drawRect
##
# ------------------------------------------------------------------------------
#Method SkColor getColor(int x, int y) const
#In Property
#In Pixels
#Line # returns one pixel as Unpremultiplied Color ##
#Populate
#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 getAlphaf getAddr readPixels
##
#Method float getAlphaf(int x, int y) const
#In Property
#Line # returns Alpha normalized from zero to one ##
Looks up the pixel at (x,y) and return its alpha component, normalized to [0..1].
This is roughly equivalent to #Formula # SkGetColorA(getColor()) ##, but can be more efficient
(and more precise if the pixels store more than 8 bits per component).
#Param x column index, zero or greater, and less than width() ##
#Param y row index, zero or greater, and less than height() ##
#Return alpha converted to normalized float ##
#NoExample
##
#SeeAlso getColor
##
# ------------------------------------------------------------------------------
#Method void* getAddr(int x, int y) const
#In Property
#Line # returns readable pixel address as void pointer ##
#Populate
#Example
#Image 3
char* row0 = (char* ) source.getAddr(0, 0);
char* row1 = (char* ) source.getAddr(0, 1);
SkDebugf("addr interval %c= rowBytes\n",
(size_t) (row1 - row0) == source.rowBytes() ? '=' : '!');
#StdOut
addr interval == rowBytes
##
##
#SeeAlso getAddr8 getAddr16 getAddr32 readPixels SkPixmap::addr
##
# ------------------------------------------------------------------------------
#Method uint32_t* getAddr32(int x, int y) const
#In Property
#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 uint16_t* getAddr16(int x, int y) const
#In Property
#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 uint8_t* getAddr8(int x, int y) const
#In Property
#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
#In Constructors
#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) const
#In Pixels
#Line # copies and converts pixels ##
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 has no address ##
# 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)
#In Pixels
#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 extractAlpha(SkBitmap* dst) const
#In Constructors
#Line # creates Bitmap containing Alpha of pixels ##
#Populate
#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
#Populate
#Example
#Height 160
auto radiusToSigma = [](SkScalar radius) -> SkScalar {
static const SkScalar kBLUR_SIGMA_SCALE = 0.57735f;
return radius > 0 ? kBLUR_SIGMA_SCALE * radius + 0.5f : 0.0f;
};
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(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, radiusToSigma(25)));
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
#Populate
#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(SkMaskFilter::MakeBlur(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
#In Pixels
#Line # returns Pixmap if possible ##
#Populate
#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
##
# ------------------------------------------------------------------------------
#Subtopic Utility
#Line # rarely called management functions ##
##
#Method void validate() const;
#In Utility
#Line # asserts if Bitmap is invalid (debug only) ##
#Populate
#NoExample
##
#SeeAlso SkImageInfo::validate
##
# ------------------------------------------------------------------------------
#Class SkBitmap ##
#Topic Bitmap ##