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 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 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 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 153 virtual ~EncodeView() { 154 delete[] fBitmaps; 155 } 156 157 protected: 158 // overrides from SkEventSink 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 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 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 229 static SkView* MyFactory() { return new EncodeView; } 230 static SkViewRegister reg(MyFactory); 231 232