• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "SkData.h"
12 #include "SkDecodingImageGenerator.h"
13 #include "SkGradientShader.h"
14 #include "SkGraphics.h"
15 #include "SkImageDecoder.h"
16 #include "SkImageEncoder.h"
17 #include "SkPath.h"
18 #include "SkRegion.h"
19 #include "SkShader.h"
20 #include "SkUtils.h"
21 #include "SkXfermode.h"
22 #include "SkColorPriv.h"
23 #include "SkColorFilter.h"
24 #include "SkTime.h"
25 #include "SkTypeface.h"
26 
27 #include "SkStream.h"
28 
make_image(SkBitmap * bm,SkColorType ct,int configIndex)29 static void make_image(SkBitmap* bm, SkColorType ct, int configIndex) {
30     const int   width = 98;
31     const int   height = 100;
32     const SkImageInfo info = SkImageInfo::Make(width, height, ct, kPremul_SkAlphaType);
33 
34     SkBitmap    device;
35     device.allocN32Pixels(width, height);
36     SkCanvas    canvas(device);
37     SkPaint     paint;
38 
39     paint.setAntiAlias(true);
40     canvas.drawColor(SK_ColorRED);
41     paint.setColor(SK_ColorBLUE);
42     canvas.drawCircle(SkIntToScalar(width)/2, SkIntToScalar(height)/2,
43                       SkIntToScalar(width)/2, paint);
44 
45     switch (ct) {
46         case kN32_SkColorType:
47             bm->swap(device);
48             break;
49         case kRGB_565_SkColorType: {
50             bm->allocPixels(info);
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 kIndex_8_SkColorType: {
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(info, NULL, ctable);
69             ctable->unref();
70             for (int y = 0; y < height; y++) {
71                 for (int x = 0; x < width; x++) {
72                     *bm->getAddr8(x, y) = SkGetPackedR32(*device.getAddr32(x, y));
73                 }
74             }
75             break;
76         }
77         default:
78             SkASSERT(0);
79     }
80 }
81 
82 // configs to build the original bitmap in. Can be at most these 3
83 static const SkColorType gColorTypes[] = {
84     kN32_SkColorType,
85     kRGB_565_SkColorType,
86     kIndex_8_SkColorType,   // opaque
87     kIndex_8_SkColorType    // alpha
88 };
89 
90 static const char* const gConfigLabels[] = {
91     "8888", "565", "Index8",  "Index8 alpha"
92 };
93 
94 // types to encode into. Can be at most these 3. Must match up with gExt[]
95 static const SkImageEncoder::Type gTypes[] = {
96     SkImageEncoder::kJPEG_Type,
97     SkImageEncoder::kPNG_Type
98 };
99 
100 // must match up with gTypes[]
101 static const char* const gExt[] = {
102     ".jpg", ".png"
103 };
104 
105 #include <sys/stat.h>
106 
107 class EncodeView : public SampleView {
108 public:
109     SkBitmap*        fBitmaps;
110     SkAutoDataUnref* fEncodedPNGs;
111     SkAutoDataUnref* fEncodedJPEGs;
112     int              fBitmapCount;
113 
EncodeView()114     EncodeView() {
115         fBitmapCount = SK_ARRAY_COUNT(gColorTypes);
116         fBitmaps = new SkBitmap[fBitmapCount];
117         fEncodedPNGs = new SkAutoDataUnref[fBitmapCount];
118         fEncodedJPEGs = new SkAutoDataUnref[fBitmapCount];
119         for (int i = 0; i < fBitmapCount; i++) {
120             make_image(&fBitmaps[i], gColorTypes[i], i);
121 
122             for (size_t j = 0; j < SK_ARRAY_COUNT(gTypes); j++) {
123                 SkAutoTDelete<SkImageEncoder> codec(
124                     SkImageEncoder::Create(gTypes[j]));
125                 if (NULL == codec.get()) {
126                     SkDebugf("[%s:%d] failed to encode %s%s\n",
127                              __FILE__, __LINE__,gConfigLabels[i], gExt[j]);
128                     continue;
129                 }
130                 SkAutoDataUnref data(codec->encodeData(fBitmaps[i], 100));
131                 if (NULL == data.get()) {
132                     SkDebugf("[%s:%d] failed to encode %s%s\n",
133                              __FILE__, __LINE__,gConfigLabels[i], gExt[j]);
134                     continue;
135                 }
136                 if (SkImageEncoder::kJPEG_Type == gTypes[j]) {
137                     fEncodedJPEGs[i].reset(data.detach());
138                 } else if (SkImageEncoder::kPNG_Type == gTypes[j]) {
139                     fEncodedPNGs[i].reset(data.detach());
140                 }
141             }
142         }
143         this->setBGColor(0xFFDDDDDD);
144     }
145 
~EncodeView()146     virtual ~EncodeView() {
147         delete[] fBitmaps;
148         delete[] fEncodedPNGs;
149         delete[] fEncodedJPEGs;
150     }
151 
152 protected:
153     // overrides from SkEventSink
onQuery(SkEvent * evt)154     virtual bool onQuery(SkEvent* evt) {
155         if (SampleCode::TitleQ(*evt)) {
156             SampleCode::TitleR(evt, "ImageEncoder");
157             return true;
158         }
159         return this->INHERITED::onQuery(evt);
160     }
161 
onDrawContent(SkCanvas * canvas)162     virtual void onDrawContent(SkCanvas* canvas) {
163         if (fBitmapCount == 0) {
164             return;
165         }
166 
167         SkPaint paint;
168         paint.setAntiAlias(true);
169         paint.setTextAlign(SkPaint::kCenter_Align);
170 
171         canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
172 
173         SkScalar x = 0, y = 0, maxX = 0;
174         const int SPACER = 10;
175 
176         for (int i = 0; i < fBitmapCount; i++) {
177             canvas->drawText(gConfigLabels[i], strlen(gConfigLabels[i]),
178                              x + SkIntToScalar(fBitmaps[i].width()) / 2, 0,
179                              paint);
180             y = paint.getTextSize();
181 
182             canvas->drawBitmap(fBitmaps[i], x, y);
183 
184             SkScalar yy = y;
185             for (size_t j = 0; j < SK_ARRAY_COUNT(gTypes); j++) {
186                 yy += SkIntToScalar(fBitmaps[i].height() + 10);
187 
188                 SkBitmap bm;
189                 SkData* encoded = NULL;
190                 if (SkImageEncoder::kJPEG_Type == gTypes[j]) {
191                     encoded = fEncodedJPEGs[i].get();
192                 } else if (SkImageEncoder::kPNG_Type == gTypes[j]) {
193                     encoded = fEncodedPNGs[i].get();
194                 }
195                 if (encoded) {
196                     if (!SkInstallDiscardablePixelRef(
197                             SkDecodingImageGenerator::Create(encoded,
198                                 SkDecodingImageGenerator::Options()),
199                             &bm)) {
200                     SkDebugf("[%s:%d] failed to decode %s%s\n",
201                              __FILE__, __LINE__,gConfigLabels[i], gExt[j]);
202                     }
203                     canvas->drawBitmap(bm, x, yy);
204                 }
205             }
206 
207             x += SkIntToScalar(fBitmaps[i].width() + SPACER);
208             if (x > maxX) {
209                 maxX = x;
210             }
211         }
212 
213         y = (paint.getTextSize() + SkIntToScalar(fBitmaps[0].height())) * 3 / 2;
214         x = maxX + SkIntToScalar(10);
215         paint.setTextAlign(SkPaint::kLeft_Align);
216 
217         for (size_t j = 0; j < SK_ARRAY_COUNT(gExt); j++) {
218             canvas->drawText(gExt[j], strlen(gExt[j]), x, y, paint);
219             y += SkIntToScalar(fBitmaps[0].height() + SPACER);
220         }
221     }
222 
onFindClickHandler(SkScalar x,SkScalar y,unsigned modi)223     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y,
224                                               unsigned modi) {
225         this->inval(NULL);
226         return this->INHERITED::onFindClickHandler(x, y, modi);
227     }
228 
229 private:
230     typedef SampleView INHERITED;
231 };
232 
233 //////////////////////////////////////////////////////////////////////////////
234 
MyFactory()235 static SkView* MyFactory() { return new EncodeView; }
236 static SkViewRegister reg(MyFactory);
237