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