FilterView() { make_bm(&fBM8); fBM8.copyTo(&fBM4444, kARGB_4444_SkColorType); fBM8.copyTo(&fBM16, kRGB_565_SkColorType); fBM8.copyTo(&fBM32, kN32_SkColorType); this->setBGColor(0xFFDDDDDD); }
FilterView() { make_bm(&fBM8); fBM8.copyTo(&fBM4444, SkBitmap::kARGB_4444_Config); fBM8.copyTo(&fBM16, SkBitmap::kRGB_565_Config); fBM8.copyTo(&fBM32, SkBitmap::kARGB_8888_Config); this->setBGColor(0xFFDDDDDD); }
static ErrorBitfield compare(const SkBitmap& target, const SkBitmap& base, const SkString& name, const char* renderModeDescriptor, SkBitmap* diff) { SkBitmap copy; const SkBitmap* bm = ⌖ if (target.config() != SkBitmap::kARGB_8888_Config) { target.copyTo(©, SkBitmap::kARGB_8888_Config); bm = © } SkBitmap baseCopy; const SkBitmap* bp = &base; if (base.config() != SkBitmap::kARGB_8888_Config) { base.copyTo(&baseCopy, SkBitmap::kARGB_8888_Config); bp = &baseCopy; } force_all_opaque(*bm); force_all_opaque(*bp); const int w = bm->width(); const int h = bm->height(); if (w != bp->width() || h != bp->height()) { SkDebugf( "---- %s dimensions mismatch for %s base [%d %d] current [%d %d]\n", renderModeDescriptor, name.c_str(), bp->width(), bp->height(), w, h); return ERROR_DIMENSION_MISMATCH; } SkAutoLockPixels bmLock(*bm); SkAutoLockPixels baseLock(*bp); for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { SkPMColor c0 = *bp->getAddr32(x, y); SkPMColor c1 = *bm->getAddr32(x, y); if (c0 != c1) { SkDebugf( "----- %s pixel mismatch for %s at [%d %d] base 0x%08X current 0x%08X\n", renderModeDescriptor, name.c_str(), x, y, c0, c1); if (diff) { diff->setConfig(SkBitmap::kARGB_8888_Config, w, h); diff->allocPixels(); compute_diff(*bm, *bp, diff); } return ERROR_PIXEL_MISMATCH; } } } // they're equal return ERROR_NONE; }
FilterView() { /*做一张bitmap, kIndex8_Config格式的2行2列 依次转换成 其他3种格式的bitmap : 见结果图, 对应4行.*/ make_bm(&fBM8); fBM8.copyTo(&fBM4444, SkBitmap::kARGB_4444_Config); fBM8.copyTo(&fBM16, SkBitmap::kRGB_565_Config); fBM8.copyTo(&fBM32, SkBitmap::kARGB_8888_Config); //设置背景色 为 灰色 : 见结果图 this->setBGColor(0xFFDDDDDD); }
static void compare(const SkBitmap& target, const SkBitmap& base, const SkString& name) { SkBitmap copy; const SkBitmap* bm = ⌖ if (target.config() != SkBitmap::kARGB_8888_Config) { target.copyTo(©, SkBitmap::kARGB_8888_Config); bm = © } force_all_opaque(*bm); const int w = bm->width(); const int h = bm->height(); if (w != base.width() || h != base.height()) { SkDebugf("---- dimensions mismatch for %s base [%d %d] current [%d %d]\n", name.c_str(), base.width(), base.height(), w, h); return; } SkAutoLockPixels bmLock(*bm); SkAutoLockPixels baseLock(base); for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { SkPMColor c0 = *base.getAddr32(x, y); SkPMColor c1 = *bm->getAddr32(x, y); if (c0 != c1) { SkDebugf("----- pixel mismatch for %s at [%d %d] base 0x%08X current 0x%08X\n", name.c_str(), x, y, c0, c1); return; } } } }
bool SourceSurfaceSkia::InitFromData(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat) { SkBitmap temp; SkAlphaType alphaType = (aFormat == SurfaceFormat::B8G8R8X8) ? kOpaque_SkAlphaType : kPremul_SkAlphaType; SkImageInfo info = SkImageInfo::Make(aSize.width, aSize.height, GfxFormatToSkiaColorType(aFormat), alphaType); temp.setInfo(info, aStride); temp.setPixels(aData); if (!temp.copyTo(&mBitmap, GfxFormatToSkiaColorType(aFormat))) { return false; } if (aFormat == SurfaceFormat::B8G8R8X8) { mBitmap.setAlphaType(kIgnore_SkAlphaType); } mSize = aSize; mFormat = aFormat; mStride = mBitmap.rowBytes(); return true; }
bool SkBitmapDevice::onReadPixels(const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) { SkASSERT(SkBitmap::kARGB_8888_Config == bitmap.config()); SkASSERT(!bitmap.isNull()); SkASSERT(SkIRect::MakeWH(this->width(), this->height()).contains(SkIRect::MakeXYWH(x, y, bitmap.width(), bitmap.height()))); SkIRect srcRect = SkIRect::MakeXYWH(x, y, bitmap.width(), bitmap.height()); const SkBitmap& src = this->accessBitmap(false); SkBitmap subset; if (!src.extractSubset(&subset, srcRect)) { return false; } if (kPMColor_SkColorType != subset.colorType()) { // It'd be preferable to do this directly to bitmap. subset.copyTo(&subset, kPMColor_SkColorType); } SkAutoLockPixels alp(bitmap); uint32_t* bmpPixels = reinterpret_cast<uint32_t*>(bitmap.getPixels()); SkCopyBitmapToConfig8888(bmpPixels, bitmap.rowBytes(), config8888, subset); return true; }
bool write_bitmap(const SkString& path, const SkBitmap& bitmap) { SkBitmap copy; bitmap.copyTo(©, kN32_SkColorType); force_all_opaque(copy); return SkImageEncoder::EncodeFile(path.c_str(), copy, SkImageEncoder::kPNG_Type, 100); }
bool Scale(uint8_t* srcData, int32_t srcWidth, int32_t srcHeight, int32_t srcStride, uint8_t* dstData, int32_t dstWidth, int32_t dstHeight, int32_t dstStride, SurfaceFormat format) { #ifdef USE_SKIA SkAlphaType alphaType; if (format == SurfaceFormat::B8G8R8A8) { alphaType = kPremul_SkAlphaType; } else { alphaType = kOpaque_SkAlphaType; } SkBitmap::Config config = GfxFormatToSkiaConfig(format); SkBitmap imgSrc; imgSrc.setConfig(config, srcWidth, srcHeight, srcStride, alphaType); imgSrc.setPixels(srcData); // Rescaler is compatible with 32 bpp only. Convert to RGB32 if needed. if (config != SkBitmap::kARGB_8888_Config) { imgSrc.copyTo(&imgSrc, SkBitmap::kARGB_8888_Config); } // This returns an SkBitmap backed by dstData; since it also wrote to dstData, // we don't need to look at that SkBitmap. SkBitmap result = skia::ImageOperations::Resize(imgSrc, skia::ImageOperations::RESIZE_BEST, dstWidth, dstHeight, dstData); return !result.isNull(); #else return false; #endif }
DitherBitmapView() { test_pathregion(); fBM8 = make_bitmap(); fBM8.copyTo(&fBM32, SkBitmap::kARGB_8888_Config); this->setBGColor(0xFFDDDDDD); }
static bool write_bitmap(const SkString& path, const SkBitmap& bitmap) { SkBitmap copy; bitmap.copyTo(©, SkBitmap::kARGB_8888_Config); force_all_opaque(copy); return SkImageEncoder::EncodeFile(path.c_str(), copy, SkImageEncoder::kPNG_Type, 100); }
bool dumpAlphaTexture(int width, int height, uint8_t *data, const char *prefix, SkBitmap::Config format) { static int count = 0; char procName[256]; char file[512]; SkBitmap bitmap; SkBitmap bitmapCopy; if (!getProcessName(procName, sizeof(procName))) return false; sprintf(file, "/data/data/%s/%s_%04d.png", procName, prefix, count++); XLOGI("%s: %dx%d %s\n", __FUNCTION__, width, height, file); bitmap.setConfig(format, width, height); bitmap.setPixels(data, NULL); if (!bitmap.copyTo(&bitmapCopy, SkBitmap::kARGB_8888_Config)) { XLOGD("%s: Failed to copy data", __FUNCTION__); return false; } if (!SkImageEncoder::EncodeFile(file, bitmapCopy, SkImageEncoder::kPNG_Type, 100)) { XLOGE("%s: Failed to encode image %s\n", __FUNCTION__, file); return false; } return true; }
bool SourceSurfaceSkia::InitFromData(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat) { SkBitmap temp; temp.setConfig(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height, aStride); temp.setPixels(aData); if (!temp.copyTo(&mBitmap, GfxFormatToSkiaConfig(aFormat))) { return false; } if (aFormat == FORMAT_B8G8R8X8) { mBitmap.lockPixels(); // We have to manually set the A channel to be 255 as Skia doesn't understand BGRX ConvertBGRXToBGRA(reinterpret_cast<unsigned char*>(mBitmap.getPixels()), aSize, aStride); mBitmap.unlockPixels(); mBitmap.notifyPixelsChanged(); mBitmap.setIsOpaque(true); } mSize = aSize; mFormat = aFormat; mStride = aStride; return true; }
DitherBitmapView() { fResult = test_pathregion(); fBM8 = make_bitmap(); fBM8.copyTo(&fBM32, kN32_SkColorType); this->setBGColor(0xFFDDDDDD); }
PassRefPtr<BitmapImageSingleFrameSkia> BitmapImageSingleFrameSkia::create(const SkBitmap& bitmap) { RefPtr<BitmapImageSingleFrameSkia> image(adoptRef(new BitmapImageSingleFrameSkia())); if (!bitmap.copyTo(&image->m_nativeImage, bitmap.config())) return 0; return image.release(); }
static SkBitmap deepSkBitmapCopy(const SkBitmap& bitmap) { SkBitmap tmp; if (!bitmap.deepCopyTo(&tmp, bitmap.config())) bitmap.copyTo(&tmp, bitmap.config()); return tmp; }
PassRefPtr<BitmapImageSingleFrameSkia> BitmapImageSingleFrameSkia::create(const SkBitmap& bitmap, bool copyPixels) { if (copyPixels) { SkBitmap temp; bitmap.copyTo(&temp, bitmap.config()); return adoptRef(new BitmapImageSingleFrameSkia(temp)); } return adoptRef(new BitmapImageSingleFrameSkia(bitmap)); }
void SourceSurfaceSkia::DrawTargetWillChange() { if (mDrawTarget) { mDrawTarget = nullptr; SkBitmap temp = mBitmap; mBitmap.reset(); temp.copyTo(&mBitmap, temp.getConfig()); } }
DitherView() { make_bm(&fBM); make_bm(&fBMPreDither); pre_dither(fBMPreDither); fBM.copyTo(&fBM16, kARGB_4444_SkColorType); fAngle = 0; this->setBGColor(0xFF181818); }
DitherView() { make_bm(&fBM); make_bm(&fBMPreDither); pre_dither(fBMPreDither); fBM.copyTo(&fBM16, SkBitmap::kARGB_4444_Config); fAngle = 0; this->setBGColor(0xFF181818); }
// copyTo() should preserve isOpaque when it makes sense static void test_isOpaque(skiatest::Reporter* reporter, const SkBitmap& srcOpaque, const SkBitmap& srcPremul, SkColorType dstColorType) { SkBitmap dst; if (canHaveAlpha(srcPremul.colorType()) && canHaveAlpha(dstColorType)) { REPORTER_ASSERT(reporter, srcPremul.copyTo(&dst, dstColorType)); REPORTER_ASSERT(reporter, dst.colorType() == dstColorType); if (srcPremul.isOpaque() != dst.isOpaque()) { report_opaqueness(reporter, srcPremul, dst); } } REPORTER_ASSERT(reporter, srcOpaque.copyTo(&dst, dstColorType)); REPORTER_ASSERT(reporter, dst.colorType() == dstColorType); if (srcOpaque.isOpaque() != dst.isOpaque()) { report_opaqueness(reporter, srcOpaque, dst); } }
PassRefPtr<BitmapImageSingleFrameSkia> BitmapImageSingleFrameSkia::create(const SkBitmap& bitmap, bool copyPixels, float resolutionScale) { if (copyPixels) { SkBitmap temp; if (!bitmap.deepCopyTo(&temp, bitmap.config())) bitmap.copyTo(&temp, bitmap.config()); return adoptRef(new BitmapImageSingleFrameSkia(temp, resolutionScale)); } return adoptRef(new BitmapImageSingleFrameSkia(bitmap, resolutionScale)); }
DEF_TEST(BitmapCopy_extractSubset, reporter) { for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) { SkBitmap srcOpaque, srcPremul; setup_src_bitmaps(&srcOpaque, &srcPremul, gPairs[i].fColorType); SkBitmap bitmap(srcOpaque); SkBitmap subset; SkIRect r; // Extract a subset which has the same width as the original. This // catches a bug where we cloned the genID incorrectly. r.set(0, 1, W, 3); bitmap.setIsVolatile(true); // Relies on old behavior of extractSubset failing if colortype is unknown if (kUnknown_SkColorType != bitmap.colorType() && bitmap.extractSubset(&subset, r)) { REPORTER_ASSERT(reporter, subset.width() == W); REPORTER_ASSERT(reporter, subset.height() == 2); REPORTER_ASSERT(reporter, subset.alphaType() == bitmap.alphaType()); REPORTER_ASSERT(reporter, subset.isVolatile() == true); // Test copying an extracted subset. for (size_t j = 0; j < SK_ARRAY_COUNT(gPairs); j++) { SkBitmap copy; bool success = subset.copyTo(©, gPairs[j].fColorType); if (!success) { // Skip checking that success matches fValid, which is redundant // with the code below. REPORTER_ASSERT(reporter, gPairs[i].fColorType != gPairs[j].fColorType); continue; } // When performing a copy of an extracted subset, the gen id should // change. REPORTER_ASSERT(reporter, copy.getGenerationID() != subset.getGenerationID()); REPORTER_ASSERT(reporter, copy.width() == W); REPORTER_ASSERT(reporter, copy.height() == 2); if (gPairs[i].fColorType == gPairs[j].fColorType) { SkAutoLockPixels alp0(subset); SkAutoLockPixels alp1(copy); // they should both have, or both not-have, a colortable bool hasCT = subset.getColorTable() != nullptr; REPORTER_ASSERT(reporter, (copy.getColorTable() != nullptr) == hasCT); } } } bitmap = srcPremul; bitmap.setIsVolatile(false); if (bitmap.extractSubset(&subset, r)) { REPORTER_ASSERT(reporter, subset.alphaType() == bitmap.alphaType()); REPORTER_ASSERT(reporter, subset.isVolatile() == false); } } }
static void DrawAndFrame(SkCanvas* canvas, const SkBitmap& orig, SkScalar x, SkScalar y) { SkBitmap bm; orig.copyTo(&bm); apply_gamma(bm); canvas->drawBitmap(bm, x, y, nullptr); SkPaint paint; paint.setStyle(SkPaint::kStroke_Style); paint.setColor(0xFFFFCCCC); canvas->drawRect(SkRect::MakeIWH(bm.width(), bm.height()).makeOffset(x, y).makeOutset(0.5f, 0.5f), paint); }
XfermodesGM() { // Do all this work in a temporary so we get a deep copy, // especially of gBG. SkBitmap scratchBitmap; scratchBitmap.setConfig(SkBitmap::kARGB_4444_Config, 2, 2, 4); scratchBitmap.setPixels(gBG); scratchBitmap.setIsOpaque(true); scratchBitmap.copyTo(&fBG, SkBitmap::kARGB_4444_Config); make_bitmaps(W, H, &fSrcB, &fDstB); }
/** * Check to ensure that copying a GPU-backed SkBitmap behaved as expected. * @param reporter Used to report failures. * @param desiredConfig Config being copied to. If the copy succeeded, dst must have this Config. * @param success True if the copy succeeded. * @param src A GPU-backed SkBitmap that had copyTo or deepCopyTo called on it. * @param dst SkBitmap that was copied to. * @param deepCopy True if deepCopyTo was used; false if copyTo was used. */ static void TestIndividualCopy(skiatest::Reporter* reporter, const SkBitmap::Config desiredConfig, const bool success, const SkBitmap& src, const SkBitmap& dst, const bool deepCopy = true) { if (success) { REPORTER_ASSERT(reporter, src.width() == dst.width()); REPORTER_ASSERT(reporter, src.height() == dst.height()); REPORTER_ASSERT(reporter, dst.config() == desiredConfig); if (src.config() == dst.config()) { // FIXME: When calling copyTo (so deepCopy is false here), sometimes we copy the pixels // exactly, in which case the IDs should be the same, but sometimes we do a bitmap draw, // in which case the IDs should not be the same. Is there any way to determine which is // the case at this point? if (deepCopy) { REPORTER_ASSERT(reporter, src.getGenerationID() == dst.getGenerationID()); } REPORTER_ASSERT(reporter, src.pixelRef() != NULL && dst.pixelRef() != NULL); // Do read backs and make sure that the two are the same. SkBitmap srcReadBack, dstReadBack; { SkASSERT(src.getTexture() != NULL); bool readBack = src.pixelRef()->readPixels(&srcReadBack); REPORTER_ASSERT(reporter, readBack); } if (dst.getTexture() != NULL) { bool readBack = dst.pixelRef()->readPixels(&dstReadBack); REPORTER_ASSERT(reporter, readBack); } else { // If dst is not a texture, do a copy instead, to the same config as srcReadBack. bool copy = dst.copyTo(&dstReadBack, srcReadBack.config()); REPORTER_ASSERT(reporter, copy); } SkAutoLockPixels srcLock(srcReadBack); SkAutoLockPixels dstLock(dstReadBack); REPORTER_ASSERT(reporter, srcReadBack.readyToDraw() && dstReadBack.readyToDraw()); const char* srcP = static_cast<const char*>(srcReadBack.getAddr(0, 0)); const char* dstP = static_cast<const char*>(dstReadBack.getAddr(0, 0)); REPORTER_ASSERT(reporter, srcP != dstP); REPORTER_ASSERT(reporter, !memcmp(srcP, dstP, srcReadBack.getSize())); } else { REPORTER_ASSERT(reporter, src.getGenerationID() != dst.getGenerationID()); } } else { // dst should be unchanged from its initial state REPORTER_ASSERT(reporter, dst.config() == SkBitmap::kNo_Config); REPORTER_ASSERT(reporter, dst.width() == 0); REPORTER_ASSERT(reporter, dst.height() == 0); } }
virtual void onDraw(SkCanvas* canvas) { SkPaint paint; SkScalar horizMargin(SkIntToScalar(10)); SkScalar vertMargin(SkIntToScalar(10)); SkBitmapDevice devTmp(SkBitmap::kARGB_8888_Config, 40, 40, false); SkCanvas canvasTmp(&devTmp); draw_checks(&canvasTmp, 40, 40); SkBitmap src = canvasTmp.getTopDevice()->accessBitmap(false); for (unsigned i = 0; i < NUM_CONFIGS; ++i) { if (!src.deepCopyTo(&fDst[i], gConfigs[i])) { src.copyTo(&fDst[i], gConfigs[i]); } } canvas->clear(0xFFDDDDDD); paint.setAntiAlias(true); SkScalar width = SkIntToScalar(40); SkScalar height = SkIntToScalar(40); if (paint.getFontSpacing() > height) { height = paint.getFontSpacing(); } for (unsigned i = 0; i < NUM_CONFIGS; i++) { const char* name = gConfigNames[src.config()]; SkScalar textWidth = paint.measureText(name, strlen(name)); if (textWidth > width) { width = textWidth; } } SkScalar horizOffset = width + horizMargin; SkScalar vertOffset = height + vertMargin; canvas->translate(SkIntToScalar(20), SkIntToScalar(20)); for (unsigned i = 0; i < NUM_CONFIGS; i++) { canvas->save(); // Draw destination config name const char* name = gConfigNames[fDst[i].config()]; SkScalar textWidth = paint.measureText(name, strlen(name)); SkScalar x = (width - textWidth) / SkScalar(2); SkScalar y = paint.getFontSpacing() / SkScalar(2); canvas->drawText(name, strlen(name), x, y, paint); // Draw destination bitmap canvas->translate(0, vertOffset); x = (width - 40) / SkScalar(2); canvas->drawBitmap(fDst[i], x, 0, &paint); canvas->restore(); canvas->translate(horizOffset, 0); } }
void SourceSurfaceSkia::DrawTargetWillChange() { if (mDrawTarget) { MaybeUnlock(); mDrawTarget = nullptr; SkBitmap temp = mBitmap; mBitmap.reset(); temp.copyTo(&mBitmap, temp.colorType()); } }
bool SkBlurImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, const SkMatrix& ctm, SkBitmap* dst, SkIPoint* offset) { SkBitmap src = this->getInputResult(proxy, source, ctm, offset); if (src.config() != SkBitmap::kARGB_8888_Config) { return false; } SkAutoLockPixels alp(src); if (!src.getPixels()) { return false; } dst->setConfig(src.config(), src.width(), src.height()); dst->allocPixels(); int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX; int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY; getBox3Params(fSigma.width(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffsetX); getBox3Params(fSigma.height(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffsetY); if (kernelSizeX < 0 || kernelSizeY < 0) { return false; } if (kernelSizeX == 0 && kernelSizeY == 0) { src.copyTo(dst, dst->config()); return true; } SkBitmap temp; temp.setConfig(dst->config(), dst->width(), dst->height()); if (!temp.allocPixels()) { return false; } if (kernelSizeX > 0 && kernelSizeY > 0) { boxBlurX(src, &temp, kernelSizeX, lowOffsetX, highOffsetX); boxBlurY(temp, dst, kernelSizeY, lowOffsetY, highOffsetY); boxBlurX(*dst, &temp, kernelSizeX, highOffsetX, lowOffsetX); boxBlurY(temp, dst, kernelSizeY, highOffsetY, lowOffsetY); boxBlurX(*dst, &temp, kernelSizeX3, highOffsetX, highOffsetX); boxBlurY(temp, dst, kernelSizeY3, highOffsetY, highOffsetY); } else if (kernelSizeX > 0) { boxBlurX(src, dst, kernelSizeX, lowOffsetX, highOffsetX); boxBlurX(*dst, &temp, kernelSizeX, highOffsetX, lowOffsetX); boxBlurX(temp, dst, kernelSizeX3, highOffsetX, highOffsetX); } else if (kernelSizeY > 0) { boxBlurY(src, dst, kernelSizeY, lowOffsetY, highOffsetY); boxBlurY(*dst, &temp, kernelSizeY, highOffsetY, lowOffsetY); boxBlurY(temp, dst, kernelSizeY3, highOffsetY, highOffsetY); } return true; }
bool CopyTilesRenderer::render(SkBitmap** out) { int i = 0; bool success = true; SkBitmap dst; for (int x = 0; x < this->getViewWidth(); x += fLargeTileWidth) { for (int y = 0; y < this->getViewHeight(); y += fLargeTileHeight) { SkAutoCanvasRestore autoRestore(fCanvas, true); // Translate so that we draw the correct portion of the picture. // Perform a postTranslate so that the scaleFactor does not interfere with the // positioning. SkMatrix mat(fCanvas->getTotalMatrix()); mat.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y)); fCanvas->setMatrix(mat); // Draw the picture fCanvas->drawPicture(*fPicture); // Now extract the picture into tiles const SkBitmap& baseBitmap = fCanvas->getDevice()->accessBitmap(false); SkIRect subset; for (int tileY = 0; tileY < fLargeTileHeight; tileY += this->getTileHeight()) { for (int tileX = 0; tileX < fLargeTileWidth; tileX += this->getTileWidth()) { subset.set(tileX, tileY, tileX + this->getTileWidth(), tileY + this->getTileHeight()); SkDEBUGCODE(bool extracted =) baseBitmap.extractSubset(&dst, subset); SkASSERT(extracted); if (!fOutputDir.isEmpty()) { // Similar to write() in PictureRenderer.cpp, but just encodes // a bitmap directly. // TODO: Share more common code with write() to do this, to properly // write out the JSON summary, etc. SkString pathWithNumber; make_filepath(&pathWithNumber, fOutputDir, fInputFilename); pathWithNumber.remove(pathWithNumber.size() - 4, 4); pathWithNumber.appendf("%i.png", i++); SkBitmap copy; #if SK_SUPPORT_GPU if (isUsingGpuDevice()) { dst.pixelRef()->readPixels(©, &subset); } else { #endif dst.copyTo(©); #if SK_SUPPORT_GPU } #endif success &= SkImageEncoder::EncodeFile(pathWithNumber.c_str(), copy, SkImageEncoder::kPNG_Type, 100); } } } } } return success; }