1 #include "SampleCode.h"
2 #include "SkView.h"
3 #include "SkCanvas.h"
4 #include "SkGradientShader.h"
5 #include "SkGraphics.h"
6 #include "SkImageDecoder.h"
7 #include "SkImageEncoder.h"
8 #include "SkPath.h"
9 #include "SkRegion.h"
10 #include "SkShader.h"
11 #include "SkUtils.h"
12 #include "SkXfermode.h"
13 #include "SkColorPriv.h"
14 #include "SkColorFilter.h"
15 #include "SkTime.h"
16 #include "SkTypeface.h"
17
18 #include "SkStream.h"
19
make_image(SkBitmap * bm,SkBitmap::Config config,int configIndex)20 static void make_image(SkBitmap* bm, SkBitmap::Config config, int configIndex) {
21 const int width = 98;
22 const int height = 100;
23 SkBitmap device;
24
25 device.setConfig(SkBitmap::kARGB_8888_Config, width, height);
26 device.allocPixels();
27
28 SkCanvas canvas(device);
29 SkPaint paint;
30
31 paint.setAntiAlias(true);
32 canvas.drawColor(SK_ColorRED);
33 paint.setColor(SK_ColorBLUE);
34 canvas.drawCircle(SkIntToScalar(width)/2, SkIntToScalar(height)/2,
35 SkIntToScalar(width)/2, paint);
36
37 bm->setConfig(config, width, height);
38 switch (config) {
39 case SkBitmap::kARGB_8888_Config:
40 bm->swap(device);
41 break;
42 case SkBitmap::kRGB_565_Config: {
43 bm->allocPixels();
44 for (int y = 0; y < height; y++) {
45 for (int x = 0; x < width; x++) {
46 *bm->getAddr16(x, y) = SkPixel32ToPixel16(*device.getAddr32(x, y));
47 }
48 }
49 break;
50 }
51 case SkBitmap::kIndex8_Config: {
52 SkPMColor colors[256];
53 for (int i = 0; i < 256; i++) {
54 if (configIndex & 1) {
55 colors[i] = SkPackARGB32(255-i, 0, 0, 255-i);
56 } else {
57 colors[i] = SkPackARGB32(0xFF, i, 0, 255-i);
58 }
59 }
60 SkColorTable* ctable = new SkColorTable(colors, 256);
61 bm->allocPixels(ctable);
62 ctable->unref();
63
64 for (int y = 0; y < height; y++) {
65 for (int x = 0; x < width; x++) {
66 *bm->getAddr8(x, y) = SkGetPackedR32(*device.getAddr32(x, y));
67 }
68 }
69 break;
70 }
71 default:
72 break;
73 }
74 }
75
76 // configs to build the original bitmap in. Can be at most these 3
77 static const SkBitmap::Config gConfigs[] = {
78 SkBitmap::kARGB_8888_Config,
79 SkBitmap::kRGB_565_Config,
80 SkBitmap::kIndex8_Config, // opaque
81 SkBitmap::kIndex8_Config // alpha
82 };
83
84 static const char* const gConfigLabels[] = {
85 "8888", "565", "Index8", "Index8 alpha"
86 };
87
88 // types to encode into. Can be at most these 3. Must match up with gExt[]
89 static const SkImageEncoder::Type gTypes[] = {
90 SkImageEncoder::kJPEG_Type,
91 SkImageEncoder::kPNG_Type
92 };
93
94 // must match up with gTypes[]
95 static const char* const gExt[] = {
96 ".jpg", ".png"
97 };
98
99 static const char* gPath = "/encoded/";
100
make_name(SkString * name,int config,int ext)101 static void make_name(SkString* name, int config, int ext) {
102 name->set(gPath);
103 name->append(gConfigLabels[config]);
104 name->append(gExt[ext]);
105 }
106
107 #include <sys/stat.h>
108
109 class EncodeView : public SampleView {
110 public:
111 SkBitmap* fBitmaps;
112 size_t fBitmapCount;
113
EncodeView()114 EncodeView() {
115 #if 1
116 (void)mkdir(gPath, S_IRWXU | S_IRWXG | S_IRWXO);
117
118 fBitmapCount = SK_ARRAY_COUNT(gConfigs);
119 fBitmaps = new SkBitmap[fBitmapCount];
120 for (size_t i = 0; i < fBitmapCount; i++) {
121 make_image(&fBitmaps[i], gConfigs[i], i);
122
123 for (size_t j = 0; j < SK_ARRAY_COUNT(gExt); j++) {
124 SkString path;
125 make_name(&path, i, j);
126
127 // remove any previous run of this file
128 remove(path.c_str());
129
130 SkImageEncoder* codec = SkImageEncoder::Create(gTypes[j]);
131 if (NULL == codec ||
132 !codec->encodeFile(path.c_str(), fBitmaps[i], 100)) {
133 SkDebugf("------ failed to encode %s\n", path.c_str());
134 remove(path.c_str()); // remove any partial file
135 }
136 delete codec;
137 }
138 }
139 #else
140 fBitmaps = NULL;
141 fBitmapCount = 0;
142 #endif
143 this->setBGColor(0xFFDDDDDD);
144 }
145
~EncodeView()146 virtual ~EncodeView() {
147 delete[] fBitmaps;
148 }
149
150 protected:
151 // overrides from SkEventSink
onQuery(SkEvent * evt)152 virtual bool onQuery(SkEvent* evt) {
153 if (SampleCode::TitleQ(*evt)) {
154 SampleCode::TitleR(evt, "ImageEncoder");
155 return true;
156 }
157 return this->INHERITED::onQuery(evt);
158 }
159
onDrawContent(SkCanvas * canvas)160 virtual void onDrawContent(SkCanvas* canvas) {
161 if (fBitmapCount == 0) {
162 return;
163 }
164
165 SkPaint paint;
166 paint.setAntiAlias(true);
167 paint.setTextAlign(SkPaint::kCenter_Align);
168
169 canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
170
171 SkScalar x = 0, y = 0, maxX = 0;
172 const int SPACER = 10;
173
174 for (size_t i = 0; i < fBitmapCount; i++) {
175 canvas->drawText(gConfigLabels[i], strlen(gConfigLabels[i]),
176 x + SkIntToScalar(fBitmaps[i].width()) / 2, 0,
177 paint);
178 y = paint.getTextSize();
179
180 canvas->drawBitmap(fBitmaps[i], x, y);
181
182 SkScalar yy = y;
183 for (size_t j = 0; j < SK_ARRAY_COUNT(gExt); j++) {
184 yy += SkIntToScalar(fBitmaps[i].height() + 10);
185
186 SkBitmap bm;
187 SkString name;
188
189 make_name(&name, i, j);
190
191 SkImageDecoder::DecodeFile(name.c_str(), &bm);
192 canvas->drawBitmap(bm, x, yy);
193 }
194
195 x += SkIntToScalar(fBitmaps[i].width() + SPACER);
196 if (x > maxX) {
197 maxX = x;
198 }
199 }
200
201 y = (paint.getTextSize() + SkIntToScalar(fBitmaps[0].height())) * 3 / 2;
202 x = maxX + SkIntToScalar(10);
203 paint.setTextAlign(SkPaint::kLeft_Align);
204
205 for (size_t j = 0; j < SK_ARRAY_COUNT(gExt); j++) {
206 canvas->drawText(gExt[j], strlen(gExt[j]), x, y, paint);
207 y += SkIntToScalar(fBitmaps[0].height() + SPACER);
208 }
209 }
210
onFindClickHandler(SkScalar x,SkScalar y)211 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
212 this->inval(NULL);
213 return this->INHERITED::onFindClickHandler(x, y);
214 }
215
216 private:
217 typedef SampleView INHERITED;
218 };
219
220 //////////////////////////////////////////////////////////////////////////////
221
MyFactory()222 static SkView* MyFactory() { return new EncodeView; }
223 static SkViewRegister reg(MyFactory);
224
225