SampleEncode.cpp revision 7fa2a65c0cfc714364490cb715171461143024e0
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 29static void make_image(SkBitmap* bm, SkBitmap::Config config, int configIndex) { 30 const int width = 98; 31 const int height = 100; 32 SkBitmap device; 33 34 device.setConfig(SkBitmap::kARGB_8888_Config, width, height); 35 device.allocPixels(); 36 37 SkCanvas canvas(device); 38 SkPaint paint; 39 40 paint.setAntiAlias(true); 41 canvas.drawColor(SK_ColorRED); 42 paint.setColor(SK_ColorBLUE); 43 canvas.drawCircle(SkIntToScalar(width)/2, SkIntToScalar(height)/2, 44 SkIntToScalar(width)/2, paint); 45 46 bm->setConfig(config, width, height); 47 switch (config) { 48 case SkBitmap::kARGB_8888_Config: 49 bm->swap(device); 50 break; 51 case SkBitmap::kRGB_565_Config: { 52 bm->allocPixels(); 53 for (int y = 0; y < height; y++) { 54 for (int x = 0; x < width; x++) { 55 *bm->getAddr16(x, y) = SkPixel32ToPixel16(*device.getAddr32(x, y)); 56 } 57 } 58 break; 59 } 60 case SkBitmap::kIndex8_Config: { 61 SkPMColor colors[256]; 62 for (int i = 0; i < 256; i++) { 63 if (configIndex & 1) { 64 colors[i] = SkPackARGB32(255-i, 0, 0, 255-i); 65 } else { 66 colors[i] = SkPackARGB32(0xFF, i, 0, 255-i); 67 } 68 } 69 SkColorTable* ctable = new SkColorTable(colors, 256); 70 bm->allocPixels(ctable); 71 ctable->unref(); 72 73 for (int y = 0; y < height; y++) { 74 for (int x = 0; x < width; x++) { 75 *bm->getAddr8(x, y) = SkGetPackedR32(*device.getAddr32(x, y)); 76 } 77 } 78 break; 79 } 80 default: 81 break; 82 } 83} 84 85// configs to build the original bitmap in. Can be at most these 3 86static const SkBitmap::Config gConfigs[] = { 87 SkBitmap::kARGB_8888_Config, 88 SkBitmap::kRGB_565_Config, 89 SkBitmap::kIndex8_Config, // opaque 90 SkBitmap::kIndex8_Config // alpha 91}; 92 93static const char* const gConfigLabels[] = { 94 "8888", "565", "Index8", "Index8 alpha" 95}; 96 97// types to encode into. Can be at most these 3. Must match up with gExt[] 98static const SkImageEncoder::Type gTypes[] = { 99 SkImageEncoder::kJPEG_Type, 100 SkImageEncoder::kPNG_Type 101}; 102 103// must match up with gTypes[] 104static const char* const gExt[] = { 105 ".jpg", ".png" 106}; 107 108#include <sys/stat.h> 109 110class EncodeView : public SampleView { 111public: 112 SkBitmap* fBitmaps; 113 SkAutoDataUnref* fEncodedPNGs; 114 SkAutoDataUnref* fEncodedJPEGs; 115 int fBitmapCount; 116 117 EncodeView() { 118 #if 1 119 fBitmapCount = SK_ARRAY_COUNT(gConfigs); 120 fBitmaps = new SkBitmap[fBitmapCount]; 121 fEncodedPNGs = new SkAutoDataUnref[fBitmapCount]; 122 fEncodedJPEGs = new SkAutoDataUnref[fBitmapCount]; 123 for (int i = 0; i < fBitmapCount; i++) { 124 make_image(&fBitmaps[i], gConfigs[i], i); 125 126 for (size_t j = 0; j < SK_ARRAY_COUNT(gTypes); j++) { 127 SkAutoTDelete<SkImageEncoder> codec( 128 SkImageEncoder::Create(gTypes[j])); 129 if (NULL == codec.get()) { 130 SkDebugf("[%s:%d] failed to encode %s%s\n", 131 __FILE__, __LINE__,gConfigLabels[i], gExt[j]); 132 continue; 133 } 134 SkAutoDataUnref data(codec->encodeData(fBitmaps[i], 100)); 135 if (NULL == data.get()) { 136 SkDebugf("[%s:%d] failed to encode %s%s\n", 137 __FILE__, __LINE__,gConfigLabels[i], gExt[j]); 138 continue; 139 } 140 if (SkImageEncoder::kJPEG_Type == gTypes[j]) { 141 fEncodedJPEGs[i].reset(data.detach()); 142 } else if (SkImageEncoder::kPNG_Type == gTypes[j]) { 143 fEncodedPNGs[i].reset(data.detach()); 144 } 145 } 146 } 147 #else 148 fBitmaps = NULL; 149 fBitmapCount = 0; 150 #endif 151 this->setBGColor(0xFFDDDDDD); 152 } 153 154 virtual ~EncodeView() { 155 delete[] fBitmaps; 156 delete[] fEncodedPNGs; 157 delete[] fEncodedJPEGs; 158 } 159 160protected: 161 // overrides from SkEventSink 162 virtual bool onQuery(SkEvent* evt) { 163 if (SampleCode::TitleQ(*evt)) { 164 SampleCode::TitleR(evt, "ImageEncoder"); 165 return true; 166 } 167 return this->INHERITED::onQuery(evt); 168 } 169 170 virtual void onDrawContent(SkCanvas* canvas) { 171 if (fBitmapCount == 0) { 172 return; 173 } 174 175 SkPaint paint; 176 paint.setAntiAlias(true); 177 paint.setTextAlign(SkPaint::kCenter_Align); 178 179 canvas->translate(SkIntToScalar(10), SkIntToScalar(20)); 180 181 SkScalar x = 0, y = 0, maxX = 0; 182 const int SPACER = 10; 183 184 for (int i = 0; i < fBitmapCount; i++) { 185 canvas->drawText(gConfigLabels[i], strlen(gConfigLabels[i]), 186 x + SkIntToScalar(fBitmaps[i].width()) / 2, 0, 187 paint); 188 y = paint.getTextSize(); 189 190 canvas->drawBitmap(fBitmaps[i], x, y); 191 192 SkScalar yy = y; 193 for (size_t j = 0; j < SK_ARRAY_COUNT(gTypes); j++) { 194 yy += SkIntToScalar(fBitmaps[i].height() + 10); 195 196 SkBitmap bm; 197 SkData* encoded = NULL; 198 if (SkImageEncoder::kJPEG_Type == gTypes[j]) { 199 encoded = fEncodedJPEGs[i].get(); 200 } else if (SkImageEncoder::kPNG_Type == gTypes[j]) { 201 encoded = fEncodedPNGs[i].get(); 202 } 203 if (encoded) { 204 if (!SkInstallDiscardablePixelRef( 205 SkDecodingImageGenerator::Create(encoded, 206 SkDecodingImageGenerator::Options()), 207 &bm, NULL)) { 208 SkDebugf("[%s:%d] failed to decode %s%s\n", 209 __FILE__, __LINE__,gConfigLabels[i], gExt[j]); 210 } 211 canvas->drawBitmap(bm, x, yy); 212 } 213 } 214 215 x += SkIntToScalar(fBitmaps[i].width() + SPACER); 216 if (x > maxX) { 217 maxX = x; 218 } 219 } 220 221 y = (paint.getTextSize() + SkIntToScalar(fBitmaps[0].height())) * 3 / 2; 222 x = maxX + SkIntToScalar(10); 223 paint.setTextAlign(SkPaint::kLeft_Align); 224 225 for (size_t j = 0; j < SK_ARRAY_COUNT(gExt); j++) { 226 canvas->drawText(gExt[j], strlen(gExt[j]), x, y, paint); 227 y += SkIntToScalar(fBitmaps[0].height() + SPACER); 228 } 229 } 230 231 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, 232 unsigned modi) { 233 this->inval(NULL); 234 return this->INHERITED::onFindClickHandler(x, y, modi); 235 } 236 237private: 238 typedef SampleView INHERITED; 239}; 240 241////////////////////////////////////////////////////////////////////////////// 242 243static SkView* MyFactory() { return new EncodeView; } 244static SkViewRegister reg(MyFactory); 245