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 "SkData.h"
     12 #include "SkImageGenerator.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 
     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 
    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 
    146     virtual ~EncodeView() {
    147         delete[] fBitmaps;
    148         delete[] fEncodedPNGs;
    149         delete[] fEncodedJPEGs;
    150     }
    151 
    152 protected:
    153     // overrides from SkEventSink
    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 
    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(encoded, &bm)) {
    197                     SkDebugf("[%s:%d] failed to decode %s%s\n",
    198                              __FILE__, __LINE__,gConfigLabels[i], gExt[j]);
    199                     }
    200                     canvas->drawBitmap(bm, x, yy);
    201                 }
    202             }
    203 
    204             x += SkIntToScalar(fBitmaps[i].width() + SPACER);
    205             if (x > maxX) {
    206                 maxX = x;
    207             }
    208         }
    209 
    210         y = (paint.getTextSize() + SkIntToScalar(fBitmaps[0].height())) * 3 / 2;
    211         x = maxX + SkIntToScalar(10);
    212         paint.setTextAlign(SkPaint::kLeft_Align);
    213 
    214         for (size_t j = 0; j < SK_ARRAY_COUNT(gExt); j++) {
    215             canvas->drawText(gExt[j], strlen(gExt[j]), x, y, paint);
    216             y += SkIntToScalar(fBitmaps[0].height() + SPACER);
    217         }
    218     }
    219 
    220     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y,
    221                                               unsigned modi) {
    222         this->inval(NULL);
    223         return this->INHERITED::onFindClickHandler(x, y, modi);
    224     }
    225 
    226 private:
    227     typedef SampleView INHERITED;
    228 };
    229 
    230 //////////////////////////////////////////////////////////////////////////////
    231 
    232 static SkView* MyFactory() { return new EncodeView; }
    233 static SkViewRegister reg(MyFactory);
    234