Home | History | Annotate | Download | only in samplecode
      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