aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-20 16:33:41 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-20 16:33:41 +0000
commit4b0757b7489ee5d6bd7149bbcdb0b2af6b7a21cb (patch)
treed408b82779c2362f9888888456e0441995648fce
parent845220b8179a73c8ec3e53b6dcc11ee3d30ad6a4 (diff)
add encodeData() to SkImageEncoder, and add encoding to SkImage
BUG= R=scroggo@google.com Review URL: https://codereview.chromium.org/15002004 git-svn-id: http://skia.googlecode.com/svn/trunk@9193 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/core/SkImage.h20
-rw-r--r--include/images/SkImageEncoder.h20
-rw-r--r--src/image/SkImage.cpp31
-rw-r--r--src/image/SkImage_Base.h4
-rw-r--r--src/image/SkImage_Gpu.cpp4
-rw-r--r--src/image/SkImage_Raster.cpp6
-rw-r--r--src/images/SkImageEncoder.cpp19
-rw-r--r--tools/skhello.cpp35
8 files changed, 110 insertions, 29 deletions
diff --git a/include/core/SkImage.h b/include/core/SkImage.h
index e6ac682876..9b7dfd13b7 100644
--- a/include/core/SkImage.h
+++ b/include/core/SkImage.h
@@ -21,8 +21,6 @@ class GrTexture;
// need for TileMode
#include "SkShader.h"
-////// EXPERIMENTAL
-
/**
* SkImage is an abstraction for drawing a rectagle of pixels, though the
* particular type of image could be actually storing its data on the GPU, or
@@ -84,6 +82,24 @@ public:
void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);
+ enum EncodeType {
+ kBMP_EncodeType,
+ kGIF_EncodeType,
+ kICO_EncodeType,
+ kJPEG_EncodeType,
+ kPNG_EncodeType,
+ kWBMP_EncodeType,
+ kWEBP_EncodeType,
+ };
+ /**
+ * Encode the image's pixels and return the result as a new SkData, which
+ * the caller must manage (i.e. call unref() when they are done).
+ *
+ * If the image type cannot be encoded, or the requested encoder type is
+ * not supported, this will return NULL.
+ */
+ SkData* encode(EncodeType t = kPNG_EncodeType, int quality = 80) const;
+
protected:
SkImage(int width, int height) :
fWidth(width),
diff --git a/include/images/SkImageEncoder.h b/include/images/SkImageEncoder.h
index 2965c88805..b990aff2a6 100644
--- a/include/images/SkImageEncoder.h
+++ b/include/images/SkImageEncoder.h
@@ -11,6 +11,7 @@
#include "SkTypes.h"
class SkBitmap;
+class SkData;
class SkWStream;
class SkImageEncoder {
@@ -35,25 +36,28 @@ public:
};
/**
+ * Encode bitmap 'bm', returning the results in an SkData, at quality level
+ * 'quality' (which can be in range 0-100). If the bitmap cannot be
+ * encoded, return null. On success, the caller is responsible for
+ * calling unref() on the data when they are finished.
+ */
+ SkData* encodeData(const SkBitmap&, int quality);
+
+ /**
* Encode bitmap 'bm' in the desired format, writing results to
* file 'file', at quality level 'quality' (which can be in range
- * 0-100).
- *
- * Calls the particular implementation's onEncode() method to
- * actually do the encoding.
+ * 0-100). Returns false on failure.
*/
bool encodeFile(const char file[], const SkBitmap& bm, int quality);
/**
* Encode bitmap 'bm' in the desired format, writing results to
* stream 'stream', at quality level 'quality' (which can be in
- * range 0-100).
- *
- * Calls the particular implementation's onEncode() method to
- * actually do the encoding.
+ * range 0-100). Returns false on failure.
*/
bool encodeStream(SkWStream* stream, const SkBitmap& bm, int quality);
+ static SkData* EncodeData(const SkBitmap&, Type, int quality);
static bool EncodeFile(const char file[], const SkBitmap&, Type,
int quality);
static bool EncodeStream(SkWStream*, const SkBitmap&, Type,
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index 1169459df6..13af631b2a 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -9,6 +9,7 @@
#include "SkImagePriv.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
+#include "../images/SkImageEncoder.h"
SK_DEFINE_INST_COUNT(SkImage)
@@ -16,6 +17,10 @@ static SkImage_Base* asIB(SkImage* image) {
return static_cast<SkImage_Base*>(image);
}
+static const SkImage_Base* asIB(const SkImage* image) {
+ return static_cast<const SkImage_Base*>(image);
+}
+
uint32_t SkImage::NextUniqueID() {
static int32_t gUniqueID;
@@ -35,3 +40,29 @@ void SkImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y,
GrTexture* SkImage::getTexture() {
return asIB(this)->onGetTexture();
}
+
+static const struct {
+ SkImageEncoder::Type fIE;
+ SkImage::EncodeType fET;
+} gTable[] = {
+ { SkImageEncoder::kBMP_Type, SkImage::kBMP_EncodeType },
+ { SkImageEncoder::kGIF_Type, SkImage::kGIF_EncodeType },
+ { SkImageEncoder::kICO_Type, SkImage::kICO_EncodeType },
+ { SkImageEncoder::kJPEG_Type, SkImage::kJPEG_EncodeType },
+ { SkImageEncoder::kPNG_Type, SkImage::kPNG_EncodeType },
+ { SkImageEncoder::kWBMP_Type, SkImage::kWBMP_EncodeType },
+ { SkImageEncoder::kWEBP_Type, SkImage::kWEBP_EncodeType },
+};
+
+SkData* SkImage::encode(EncodeType et, int quality) const {
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gTable); ++i) {
+ if (gTable[i].fET == et) {
+ SkBitmap bm;
+ if (asIB(this)->getROPixels(&bm)) {
+ return SkImageEncoder::EncodeData(bm, gTable[i].fIE, quality);
+ }
+ break;
+ }
+ }
+ return NULL;
+}
diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h
index d8e64a9a75..0b3ddb43b7 100644
--- a/src/image/SkImage_Base.h
+++ b/src/image/SkImage_Base.h
@@ -16,6 +16,10 @@ public:
virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) = 0;
virtual GrTexture* onGetTexture() { return NULL; }
+
+ // return a read-only copy of the pixels. We promise to not modify them,
+ // but only inspect them (or encode them).
+ virtual bool getROPixels(SkBitmap*) const { return false; }
private:
typedef SkImage INHERITED;
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 451ad072a6..b6e4211d28 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -22,6 +22,10 @@ public:
virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) SK_OVERRIDE;
virtual GrTexture* onGetTexture() SK_OVERRIDE;
+ virtual bool getROPixels(SkBitmap*) const SK_OVERRIDE {
+ // TODO
+ return false;
+ }
GrTexture* getTexture() { return fTexture; }
diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp
index 4a18f4aef2..5e1e8a02f3 100644
--- a/src/image/SkImage_Raster.cpp
+++ b/src/image/SkImage_Raster.cpp
@@ -55,6 +55,7 @@ public:
virtual ~SkImage_Raster();
virtual void onDraw(SkCanvas*, SkScalar, SkScalar, const SkPaint*) SK_OVERRIDE;
+ virtual bool getROPixels(SkBitmap*) const SK_OVERRIDE;
// exposed for SkSurface_Raster via SkNewImageFromPixelRef
SkImage_Raster(const SkImage::Info&, SkPixelRef*, size_t rowBytes);
@@ -108,6 +109,11 @@ void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPa
canvas->drawBitmap(fBitmap, x, y, paint);
}
+bool SkImage_Raster::getROPixels(SkBitmap* dst) const {
+ *dst = fBitmap;
+ return true;
+}
+
///////////////////////////////////////////////////////////////////////////////
SkImage* SkImage::NewRasterCopy(const SkImage::Info& info, const void* pixels, size_t rowBytes) {
diff --git a/src/images/SkImageEncoder.cpp b/src/images/SkImageEncoder.cpp
index 4b52fcdc8c..5f5ffb82a2 100644
--- a/src/images/SkImageEncoder.cpp
+++ b/src/images/SkImageEncoder.cpp
@@ -1,4 +1,3 @@
-
/*
* Copyright 2009 The Android Open Source Project
*
@@ -6,7 +5,6 @@
* found in the LICENSE file.
*/
-
#include "SkImageEncoder.h"
#include "SkBitmap.h"
#include "SkStream.h"
@@ -27,6 +25,15 @@ bool SkImageEncoder::encodeFile(const char file[], const SkBitmap& bm,
return this->onEncode(&stream, bm, quality);
}
+SkData* SkImageEncoder::encodeData(const SkBitmap& bm, int quality) {
+ SkDynamicMemoryWStream stream;
+ quality = SkMin32(100, SkMax32(0, quality));
+ if (this->onEncode(&stream, bm, quality)) {
+ return stream.copyToData();
+ }
+ return NULL;
+}
+
bool SkImageEncoder::EncodeFile(const char file[], const SkBitmap& bm, Type t,
int quality) {
SkAutoTDelete<SkImageEncoder> enc(SkImageEncoder::Create(t));
@@ -34,7 +41,13 @@ bool SkImageEncoder::EncodeFile(const char file[], const SkBitmap& bm, Type t,
}
bool SkImageEncoder::EncodeStream(SkWStream* stream, const SkBitmap& bm, Type t,
- int quality) {
+ int quality) {
SkAutoTDelete<SkImageEncoder> enc(SkImageEncoder::Create(t));
return enc.get() && enc.get()->encodeStream(stream, bm, quality);
}
+
+SkData* SkImageEncoder::EncodeData(const SkBitmap& bm, Type t, int quality) {
+ SkAutoTDelete<SkImageEncoder> enc(SkImageEncoder::Create(t));
+ return enc.get() ? enc.get()->encodeData(bm, quality) : NULL;
+}
+
diff --git a/tools/skhello.cpp b/tools/skhello.cpp
index a4451ac91a..3b8ddee9a6 100644
--- a/tools/skhello.cpp
+++ b/tools/skhello.cpp
@@ -7,8 +7,11 @@
#include "SkCanvas.h"
#include "SkCommandLineFlags.h"
+#include "SkData.h"
#include "SkGraphics.h"
-#include "SkImageEncoder.h"
+#include "SkSurface.h"
+#include "SkImage.h"
+#include "SkStream.h"
#include "SkString.h"
DEFINE_string2(outFile, o, "skhello.png", "The filename to write the image.");
@@ -33,29 +36,29 @@ int tool_main(int argc, char** argv) {
SkPaint paint;
paint.setAntiAlias(true);
paint.setTextSize(SkIntToScalar(30));
+ paint.setTextAlign(SkPaint::kCenter_Align);
+
SkScalar width = paint.measureText(text.c_str(), text.size());
SkScalar spacing = paint.getFontSpacing();
int w = SkScalarRound(width) + 30;
int h = SkScalarRound(spacing) + 30;
- SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, w, h);
- bitmap.allocPixels();
- SkCanvas canvas(bitmap);
- canvas.drawColor(SK_ColorWHITE);
+ SkImage::Info info = {
+ w, h, SkImage::kPMColor_ColorType, SkImage::kPremul_AlphaType
+ };
+ SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
+ SkCanvas* canvas = surface->getCanvas();
- paint.setTextAlign(SkPaint::kCenter_Align);
- canvas.drawText(text.c_str(), text.size(),
- SkIntToScalar(w)/2, SkIntToScalar(h)*2/3,
- paint);
+ canvas->drawColor(SK_ColorWHITE);
+ canvas->drawText(text.c_str(), text.size(),
+ SkIntToScalar(w)/2, SkIntToScalar(h)*2/3,
+ paint);
- bool success = SkImageEncoder::EncodeFile(path.c_str(), bitmap,
- SkImageEncoder::kPNG_Type, 100);
- if (!success) {
- SkDebugf("--- failed to write %s\n", path.c_str());
- }
- return !success;
+ SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
+ SkAutoDataUnref data(image->encode());
+ SkFILEWStream stream(path.c_str());
+ return stream.write(data->data(), data->size());
}
#if !defined SK_BUILD_FOR_IOS