Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(436)

Side by Side Diff: samplecode/SampleUnpremul.cpp

Issue 16410009: Add an option to create unpremultiplied bitmaps. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7 #include "gm.h"
8 #include "SampleCode.h"
9 #include "SkBlurDrawLooper.h"
10 #include "SkCanvas.h"
11 #include "SkForceLinking.h"
12 #include "SkImageDecoder.h"
13 #include "SkOSFile.h"
14 #include "SkStream.h"
15 #include "SkString.h"
16 #include "SkSystemEventTypes.h"
17 #include "SkTypes.h"
18 #include "SkUtils.h"
19 #include "SkView.h"
20
21 __SK_FORCE_IMAGE_DECODER_LINKING;
22
23 // Defined in SampleColorFilter.cpp
24 extern SkShader* createChecker();
25
26 class UnpremulView : public SampleView {
27 public:
28 UnpremulView(SkString res)
29 : fResPath(res)
30 , fPremul(true)
31 , fDecodeSucceeded(false) {
32 this->nextImage();
33 }
34
35 protected:
36 // overrides from SkEventSink
37 virtual bool onQuery(SkEvent* evt) SK_OVERRIDE {
38 if (SampleCode::TitleQ(*evt)) {
39 SampleCode::TitleR(evt, "unpremul");
40 return true;
41 }
42 SkUnichar uni;
43 if (SampleCode::CharQ(*evt, &uni)) {
44 char utf8[kMaxBytesInUTF8Sequence];
45 size_t size = SkUTF8_FromUnichar(uni, utf8);
46 // Only consider events for single char keys
47 if (1 == size) {
48 switch (utf8[0]) {
49 case fNextImageChar:
50 this->nextImage();
51 return true;
52 case fTogglePremulChar:
53 this->togglePremul();
54 return true;
55 default:
56 break;
57 }
58 }
59 }
60 return this->INHERITED::onQuery(evt);
61 }
62
63 virtual void onDrawBackground(SkCanvas* canvas) SK_OVERRIDE {
64 SkPaint paint;
65 SkAutoTUnref<SkShader> shader(createChecker());
66 paint.setShader(shader.get());
67 canvas->drawPaint(paint);
68 }
69
70 virtual void onDrawContent(SkCanvas* canvas) SK_OVERRIDE {
71 SkPaint paint;
72 paint.setAntiAlias(true);
73 paint.setTextSize(SkIntToScalar(24));
74 SkAutoTUnref<SkBlurDrawLooper> looper(SkNEW_ARGS(SkBlurDrawLooper,
75 (SkIntToScalar(2), 0, 0, SK_ColorB LUE)));
76 paint.setLooper(looper);
77 SkScalar height = paint.getFontMetrics(NULL);
78 if (!fDecodeSucceeded) {
79 SkString failure;
80 if (fResPath.size() == 0) {
81 failure.printf("resource path is required!");
82 } else {
83 failure.printf("Failed to decode %s", fCurrFile.c_str());
84 }
85 canvas->drawText(failure.c_str(), failure.size(), 0, height, paint);
86 return;
87 }
88
89 // Name, size of the file, and whether or not it is premultiplied.
90 SkString header(SkOSPath::SkBasename(fCurrFile.c_str()));
91 header.appendf(" [%dx%d] %s", fBitmap.width(), fBitmap.height(),
92 (fBitmap.premultiplied() ? "premultiplied" : "unpremultip lied"));
93 canvas->drawText(header.c_str(), header.size(), 0, height, paint);
94 canvas->translate(0, height);
95
96 // Help messages
97 header.printf("Press '%c' to move to the next image.'", fNextImageChar);
98 canvas->drawText(header.c_str(), header.size(), 0, height, paint);
99 canvas->translate(0, height);
100
101 header.printf("Press '%c' to toggle premultiplied decode.", fTogglePremu lChar);
102 canvas->drawText(header.c_str(), header.size(), 0, height, paint);
103
104 // Now draw the image itself.
105 canvas->translate(height * 2, height * 2);
106 if (!fBitmap.premultiplied()) {
107 SkASSERT(!fPremul);
108 // A premultiplied bitmap cannot currently be drawn.
109 SkAutoLockPixels alp(fBitmap);
110 SkASSERT(!fBitmap.readyToDraw());
111 // Copy it to a bitmap which can be drawn, converting
112 // to premultiplied:
113 SkBitmap bm;
114 bm.setConfig(SkBitmap::kARGB_8888_Config, fBitmap.width(),
115 fBitmap.height(), 0, true);
116 SkASSERT(fBitmap.config() == SkBitmap::kARGB_8888_Config);
117 if (!bm.allocPixels()) {
118 SkString errMsg("allocPixels failed");
119 canvas->drawText(errMsg.c_str(), errMsg.size(), 0, height, paint );
120 return;
121 }
122 for (int i = 0; i < fBitmap.width(); ++i) {
123 for (int j = 0; j < fBitmap.height(); ++j) {
124 *bm.getAddr32(i, j) = SkPreMultiplyUnPMColor(*fBitmap.getAdd r32(i, j));
125 }
126 }
127 canvas->drawBitmap(bm, 0, 0);
128 } else {
129 canvas->drawBitmap(fBitmap, 0, 0);
130 }
131 }
132
133 private:
134 const SkString fResPath;
135 SkString fCurrFile;
136 bool fPremul;
137 bool fDecodeSucceeded;
138 SkBitmap fBitmap;
139 SkOSFile::Iter fFileIter;
140
141 static const char fNextImageChar = 'j';
142 static const char fTogglePremulChar = 'h';
143
144 void nextImage() {
145 if (fResPath.size() == 0) {
146 return;
147 }
148 SkString basename;
149 if (!fFileIter.next(&basename)) {
150 fFileIter.reset(fResPath.c_str());
151 if (!fFileIter.next(&basename)) {
152 // Perhaps this should draw some error message?
153 return;
154 }
155 }
156 fCurrFile = SkOSPath::SkPathJoin(fResPath.c_str(), basename.c_str());
157 this->decodeCurrFile();
158 }
159
160 void decodeCurrFile() {
161 if (fCurrFile.size() == 0) {
162 fDecodeSucceeded = false;
163 return;
164 }
165 SkFILEStream stream(fCurrFile.c_str());
166 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream));
167 if (NULL == decoder.get()) {
168 fDecodeSucceeded = false;
169 return;
170 }
171 if (!fPremul) {
172 decoder->setRequestUnpremultipliedColors(true);
173 }
174 fDecodeSucceeded = decoder->decode(&stream, &fBitmap,
175 SkBitmap::kARGB_8888_Config,
176 SkImageDecoder::kDecodePixels_Mode);
177 this->inval(NULL);
178 }
179
180 void togglePremul() {
181 fPremul = !fPremul;
182 this->decodeCurrFile();
183 }
184
185 typedef SampleView INHERITED;
186 };
187
188 //////////////////////////////////////////////////////////////////////////////
189
190 static SkView* MyFactory() {
191 return new UnpremulView(skiagm::GM::GetResourcePath());
192 }
193 static SkViewRegister reg(MyFactory);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698