/[alephone]/aorta/image_ext.cpp
ViewVC logotype

Contents of /aorta/image_ext.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (show annotations)
Tue Jun 13 03:18:34 2006 UTC (6 years, 11 months ago) by ghs
Branch: MAIN
Changes since 1.3: +40 -28 lines
split reconstruct colors off into a separate function
allow choosing the background color for reconstructing colors

1 /*
2
3 image_ext.cpp: extra functionality for wxImage
4 Copyright (C) 2006 Gregory Smith
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19
20 */
21
22 #include "image_ext.h"
23
24 void wxImageExt::White()
25 {
26 int NumBytes = GetWidth() * GetHeight() * 3;
27 for (int i = 0; i < NumBytes; i++)
28 {
29 GetData()[i] = 0xff;
30 }
31 }
32
33 void wxImageExt::RemoveAlpha()
34 {
35 wxImageExt image;
36 image.Create(GetWidth(), GetHeight());
37 memcpy(image.GetData(), GetData(), GetWidth() * GetHeight() * 3);
38
39 *this = image;
40 }
41
42 void wxImageExt::MaskToAlpha()
43 {
44 wxImageExt image;
45 image.Create(GetWidth(), GetHeight());
46 image.InitAlpha();
47 image.SetMask(false);
48
49 memcpy(image.GetData(), GetData(), GetWidth() * GetHeight() * 3);
50
51 for (int x = 0; x < GetWidth(); x++)
52 {
53 for (int y = 0; y < GetHeight(); y++)
54 {
55 if (IsTransparent(x, y))
56 {
57 image.GetAlpha()[x + y * GetWidth()] = 0x00;
58 }
59 else
60 {
61 image.GetAlpha()[x + y * GetWidth()] = 0xff;
62 }
63 }
64 }
65
66 *this = image;
67 }
68
69 void wxImageExt::PropRescale(int width, int height)
70 {
71 float scale = (float) MAX(width, height) / MAX(GetWidth(), GetHeight());
72 Rescale((int) (GetWidth() * scale), (int) (GetHeight() * scale));
73 Resize(wxSize(width, height), wxPoint((width - GetWidth()) / 2, (height - GetHeight()) / 2));
74 }
75
76 void wxImageExt::FromAlpha(const wxImageExt& source)
77 {
78 Create(source.GetWidth(), source.GetHeight());
79 int NumPixels = GetWidth() * GetHeight();
80 for (int i = 0; i < NumPixels; i++)
81 {
82 GetData()[i * 3 + 0] = GetData()[i * 3 + 1] = GetData()[i * 3 + 2] = source.GetAlpha()[i];
83 }
84 }
85
86 void wxImageExt::ToAlpha(wxImageExt& dest) const
87 {
88 if (!dest.HasAlpha())
89 {
90 dest.InitAlpha();
91 }
92
93 int NumPixels = GetWidth() * GetHeight();
94 for (int i = 0; i < NumPixels; i++)
95 {
96 unsigned int Average = (GetData()[i * 3 + 0] + GetData()[i * 3 + 1] + GetData()[i * 3 + 2]) / 3;
97 dest.GetAlpha()[i] = Average & 0xff;
98 }
99 }
100
101 void wxImageExt::MakeOpacTypeTwo()
102 {
103 wxImageExt image;
104 image.Create(GetWidth(), GetHeight());
105 int NumPixels = GetWidth() * GetHeight();
106 for (int i = 0; i < NumPixels; i++)
107 {
108 unsigned int Average = (GetData()[i * 3 + 0] + GetData()[i * 3 + 1] + GetData()[i * 3 + 2]) / 3;
109 image.GetData()[i * 3 + 0] = image.GetData()[i * 3 + 1] = image.GetData()[i * 3 + 2] = Average & 0xff;
110 }
111
112 *this = image;
113 }
114
115 void wxImageExt::MakeOpacTypeThree()
116 {
117 wxImageExt image;
118 image.Create(GetWidth(), GetHeight());
119 int NumPixels = GetWidth() * GetHeight();
120 for (int i = 0; i < NumPixels; i++)
121 {
122 unsigned char Max = MAX(GetData()[i * 3 + 0], MAX(GetData()[i * 3 + 1], GetData()[i * 3 + 2]));
123 image.GetData()[i * 3 + 0] = image.GetData()[i * 3 + 1] = image.GetData()[i * 3 + 2] = Max;
124 }
125
126 *this = image;
127 }
128
129 // thanks to the Virtual Terrain Project for these algorithms, and the code looks
130 // pretty similar too...
131
132 void wxImageExt::ReconstructColors(const wxColour& bgColor)
133 {
134 // restore the color of edge texels by guessing correct non-background color
135 wxImageExt result;
136
137 result.Create(GetWidth(), GetHeight());
138 result.InitAlpha();
139 for (int x = 0; x < GetWidth(); x++) {
140 for (int y = 0; y < GetHeight(); y++) {
141 if (GetAlpha(x, y) == 0) {
142 result.SetAlpha(x, y, 0);
143 result.SetRGB(x, y, bgColor.Red(), bgColor.Green(), bgColor.Blue());
144 } else if (GetAlpha(x, y) == 0xff) {
145 result.SetAlpha(x, y, 0xff);
146 result.SetRGB(x, y, GetRed(x, y), GetGreen(x, y), GetBlue(x, y));
147 } else {
148 float blend_factor = GetAlpha(x, y) / 255.0f;
149 result.SetAlpha(x, y, GetAlpha(x, y));
150 short rDiff = GetRed(x, y) - bgColor.Red();
151 short gDiff = GetGreen(x, y) - bgColor.Green();
152 short bDiff = GetBlue(x, y) - bgColor.Blue();
153
154 result.SetRGB(x, y, PIN(bgColor.Red() + (int) (rDiff * (1.0f / blend_factor)), 0, 255), PIN(bgColor.Green() + (int) (gDiff * (1.0f / blend_factor)), 0, 255), PIN(bgColor.Blue() + (int) (bDiff * (1.0f / blend_factor)), 0, 255));
155 }
156 }
157 }
158
159 *this = result;
160 }
161
162 void wxImageExt::PrepareForMipmaps()
163 {
164 if (!HasAlpha()) return;
165 wxBusyCursor();
166
167 wxImageExt result = *this;
168 // scan for background pixels
169 int numBackgroundPixels = 0;
170 for (int x = 0; x < GetWidth(); x++) {
171 for (int y = 0; y < GetWidth(); y++) {
172 if (GetAlpha(x, y) == 0) {
173 numBackgroundPixels++;
174 }
175 }
176 }
177 wxProgressDialog pd(_T("Processing"), _T("Processing background pixels"), numBackgroundPixels, NULL, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_ELAPSED_TIME);
178
179 wxImageExt tempImage;
180 tempImage.Create(GetWidth(), GetHeight());
181 tempImage.InitAlpha();
182 int filled_in = 1;
183 while (filled_in) {
184 filled_in = 0;
185 int numBackgroundPixelsRemaining = 0;
186 tempImage.Create(GetWidth(), GetHeight(), true);
187
188 short rSum, gSum, bSum, aSum;
189 int surround;
190 for (int i = 0; i < GetWidth(); i++) {
191 for (int j = 0; j < GetHeight(); j++) {
192 if (result.GetAlpha(i, j) != 0)
193 continue;
194
195 numBackgroundPixelsRemaining++;
196 rSum = gSum = bSum = aSum = 0;
197 surround = 0;
198 for (int x = -1; x <= 1; x++)
199 for (int y = -1; y <= 1; y++) {
200 if (x == 0 && y == 0) continue;
201 if (i + x < 0) continue;
202 if (i + x > GetWidth() - 1) continue;
203 if (j + y < 0) continue;
204 if (j + y > GetHeight() - 1) continue;
205 if (result.GetAlpha(i + x, j + y) != 0) {
206 rSum += result.GetRed(i + x, j + y);
207 gSum += result.GetGreen(i + x, j + y);
208 bSum += result.GetBlue(i + x, j + y);
209 aSum += result.GetAlpha(i + x, j + y);
210 surround++;
211 }
212 }
213
214 if (surround > 2)
215 {
216 tempImage.SetRGB(i, j, rSum / surround, gSum / surround, bSum / surround);
217 tempImage.SetAlpha(i, j, aSum / surround);
218 }
219 }
220 }
221
222 for (int i = 0; i < GetWidth(); i++)
223 {
224 for (int j = 0; j < GetHeight(); j++)
225 {
226 if (result.GetAlpha(i, j) == 0) {
227 if (tempImage.GetRed(i, j) != 0 || tempImage.GetGreen(i, j) != 0 || tempImage.GetBlue(i, j) != 0) {
228 result.SetRGB(i, j, tempImage.GetRed(i, j), tempImage.GetGreen(i, j), tempImage.GetBlue(i, j));
229 result.SetAlpha(i, j, 1);
230 filled_in++;
231 }
232 }
233 }
234 }
235 pd.Update(numBackgroundPixels - numBackgroundPixelsRemaining);
236 }
237
238 pd.Update(numBackgroundPixels);
239
240 for (int i = 0; i < GetWidth(); i++) {
241 for (int j = 0; j < GetHeight(); j++) {
242 if (result.GetAlpha(i, j) == 1) result.SetAlpha(i, j, 0);
243 }
244 }
245
246 *this = result;
247 }

Christian Bauer">Christian Bauer
ViewVC Help
Powered by ViewVC 1.1.15