Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(405)

Unified Diff: src/image/SkImage.cpp

Issue 1390913005: add applyFilter() to SkImage (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase to new effect factories, use stroke to show image bounds Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/image/SkImage.cpp
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index af9c27592c527e1383136f999ba56ede955eb07d..3ad80043da2f49e841e546346efca82a0f712171 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -67,6 +67,81 @@ void SkImage::preroll(GrContext* ctx) const {
}
}
+SkImage* SkImage::applyFilter(SkImageFilter* filter, SkIPoint* offset,
+ bool forceResultToOriginalSize) const {
+ if (!filter) {
+ return nullptr;
+ }
+
+ SkIPoint offsetStorage;
+ if (!offset) {
+ offset = &offsetStorage;
+ }
+ return as_IB(this)->onApplyFilter(filter, offset, forceResultToOriginalSize);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "SkImageFilter.h"
+#include "SkBitmapDevice.h"
+
+static SkIRect compute_fast_ibounds(SkImageFilter* filter, const SkIRect& srcBounds) {
+ SkRect fastBounds;
+ fastBounds.set(srcBounds);
+ filter->computeFastBounds(fastBounds, &fastBounds);
+ return fastBounds.roundOut();
+}
+
+class SkRasterImageFilterProxy : public SkImageFilter::Proxy {
+public:
+ SkBaseDevice* createDevice(int width, int height) override {
+ return SkBitmapDevice::Create(SkImageInfo::MakeN32Premul(width, height));
+ }
+
+ bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImageFilter::Context&,
+ SkBitmap*, SkIPoint*) override {
+ return false;
+ }
+};
+
+SkImage* SkImage_Base::onApplyFilter(SkImageFilter* filter, SkIPoint* offsetResult,
+ bool forceResultToOriginalSize) const {
+ SkBitmap src;
+ if (!this->getROPixels(&src)) {
+ return nullptr;
+ }
+
+ const SkIRect srcBounds = SkIRect::MakeWH(this->width(), this->height());
+
+ if (forceResultToOriginalSize) {
+ const SkIRect clipBounds = srcBounds;
+ SkRasterImageFilterProxy proxy;
+ SkImageFilter::Context ctx(SkMatrix::I(), clipBounds, SkImageFilter::Cache::Get());
+
+ SkBitmap dst;
+ if (filter->filterImage(&proxy, src, ctx, &dst, offsetResult)) {
+ dst.setImmutable();
+ return SkImage::NewFromBitmap(dst);
+ }
+ } else {
+ const SkIRect dstR = compute_fast_ibounds(filter, srcBounds);
+
+ SkImageInfo info = SkImageInfo::MakeN32Premul(dstR.width(), dstR.height());
+ SkAutoTUnref<SkSurface> surface(this->onNewSurface(info));
+
+ SkPaint paint;
+ paint.setImageFilter(filter);
+ surface->getCanvas()->drawImage(this, SkIntToScalar(-dstR.x()), SkIntToScalar(-dstR.y()),
+ &paint);
+
+ offsetResult->set(dstR.x(), dstR.y());
+ return surface->newImageSnapshot();
+ }
+ return nullptr;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
SkShader* SkImage::newShader(SkShader::TileMode tileX,
SkShader::TileMode tileY,
const SkMatrix* localMatrix) const {
« no previous file with comments | « src/gpu/SkGpuDevice.cpp ('k') | src/image/SkImage_Base.h » ('j') | src/image/SkImage_Gpu.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698