1 /****************************************************************************
4 Copyright (c) 2003 Jerome Jacovella-St-Louis
7 pictureEdit.ec - Picture Editor Control
8 ****************************************************************************/
15 #define ID_IMAGE_MODE_COLORTABLE 9
16 #define ID_IMAGE_MODE_INDEXED 10
17 #define ID_IMAGE_MODE_RGB 11
19 static Array<FileFilter> filters
21 { $"Image Files (*.jpg, *.jpeg, *.bmp, *.pcx, *.png, *.gif)", "jpg, jpeg, bmp, pcx, png, gif" },
22 { $"All files", null }
25 static Array<FileType> types
27 { $"Based on extension", null, never },
28 { $"JPG Image", "jpg", always },
29 { $"BMP Image", "bmp", always },
30 { $"PCX Image", "pcx", always },
31 { $"PNG Image", "png", always },
32 { $"GIF Image", "gif", always }
35 FileDialog pictureEditFileDialog { filters = filters.array, sizeFilters = filters.count * sizeof(FileFilter), types = types.array, sizeTypes = types.count * sizeof(FileType) };
37 class PictureEdit : Window
41 isActiveClient = true;
48 char fileName[MAX_LOCATION];
50 Bitmap bitmapNotIndexed;
52 //saveDialog = pictureEditFileDialog;
54 Menu fileMenu { menu, $"File", f };
55 MenuItem { fileMenu, $"Save", s, ctrlS, NotifySelect = MenuFileSave };
56 MenuItem { fileMenu, $"Save As...", a, NotifySelect = MenuFileSaveAs };
57 Menu imageMenu { menu, $"Image", i };
58 Menu modeMenu { imageMenu, $"Mode", m };
59 MenuItem imageModeIndexedItem
61 modeMenu, $"Indexed Color...", i, isRadio = true;
62 bool NotifySelect(MenuItem selection, Modifiers mods)
66 ColorAlpha * palette = bitmap.Quantize(0, 255);
67 bitmapNotIndexed = { };
68 bitmapNotIndexed.Copy(bitmap);
69 bitmapNotIndexed.Convert(null, pixelFormat888, null);
72 eBitmap_Convert(null, bitmap, PixelFormat8, palette);
73 bitmap.allocatePalette = true;
76 imageModeColorTableItem.disabled = false;
78 modifiedDocument = true;
83 MenuItem imageModeRGBItem
85 modeMenu, $"RGB Color", r, isRadio = true;
86 bool NotifySelect(MenuItem selection, Modifiers mods)
89 bitmap.Convert(null, pixelFormat888, null);
90 delete bitmapNotIndexed;
91 imageModeColorTableItem.disabled = true;
93 modifiedDocument = true;
97 MenuDivider { modeMenu };
98 MenuItem imageModeColorTableItem
100 modeMenu, $"Color Table", r;
101 bool NotifySelect(MenuItem selection, Modifiers mods)
105 PictureEditColorTable colorTable { master = this };
113 MenuDivider { imageMenu };
114 MenuItem adjustHSVItem
116 imageMenu, $"Adjust Hue, Saturation, Value", h;
117 bool NotifySelect(MenuItem selection, Modifiers mods)
121 AdjustHSV adjustHSV { master = this };
130 property const char * bitmapFile
136 strcpy(fileName, value);
141 if(bitmap.Load(fileName, null, null))
143 if(bitmap.pixelFormat == pixelFormatRGBA)
145 bitmap.alphaBlend = true;
146 bitmap.Convert(null, pixelFormat888, null);
148 if(bitmap.pixelFormat == pixelFormat8)
150 bitmapNotIndexed = { };
151 bitmapNotIndexed.Copy(bitmap);
152 bitmapNotIndexed.Convert(null, pixelFormat888, null);
154 //if(!eWindow_GetStartWidth(window) || !eWindow_GetStartHeight(window))
156 Size size = initSize; // what's the use of retrieving initSize
157 size.w = bitmap.width;
158 size.h = bitmap.height;
162 Move(eWindow_GetStartX(window), eWindow_GetStartY(window),
163 (!eWindow_GetStartWidth(window)) ? (A_CLIENT|bitmap.width) : eWindow_GetStartWidth(window),
164 (!eWindow_GetStartHeight(window)) ? (A_CLIENT|bitmap.height) : eWindow_GetStartHeight(window));
168 Move(eWindow_GetStartX(window), eWindow_GetStartY(window),
169 (!) ? (A_CLIENT|bitmap.width) : eWindow_GetStartWidth(window),
170 (!eWindow_GetStartHeight(window)) ? (A_CLIENT|bitmap.height) : eWindow_GetStartHeight(window));
173 scrollArea = Size { bitmap.width, bitmap.height };
181 switch(bitmap.pixelFormat)
184 imageModeIndexedItem.checked = true;
187 imageModeRGBItem.checked = true;
188 imageModeColorTableItem.disabled = true;
195 void OnRedraw(Surface surface)
197 Bitmap bmp = (bitmapNotIndexed && displaySystem.pixelFormat != pixelFormat8) ? bitmapNotIndexed : bitmap;
200 int w = (int)(bmp.width * zoomFactor);
201 int h = (int)(bmp.height * zoomFactor);
202 if(w == bmp.width && h == bmp.height)
205 Max(0, (clientSize.w - w) / 2), Max(0, (clientSize.h - h) / 2),
206 scroll.x, scroll.y, w, h);
211 Max(0, (clientSize.w - w) / 2), Max(0, (clientSize.h - h) / 2),
212 (int)(scroll.x / zoomFactor), (int)(scroll.y / zoomFactor), w, h,
213 bmp.width, bmp.height);
218 void OnScroll(ScrollBarAction action, int position, Key key)
223 bool OnKeyHit(Key key, unichar ch)
229 if(bitmap && zoomFactor < 25)
231 float x = 0.5f, y = 0.5f;
232 if(bitmap.width * zoomFactor > clientSize.w)
233 x = scroll.x / (bitmap.width * zoomFactor - clientSize.w);
234 if(bitmap.height * zoomFactor > clientSize.h)
235 y = scroll.y / (bitmap.height * zoomFactor - clientSize.h);
238 scrollArea = Size { bitmap.width * zoomFactor, bitmap.height * zoomFactor };
241 (int)(Max(0, bitmap.width * zoomFactor - clientSize.w) * x),
242 (int)(Max(0, bitmap.height * zoomFactor - clientSize.h) * y) };
249 if(bitmap && zoomFactor > 0.05)
251 float x = 0.5f, y = 0.5f;
252 if(bitmap.width * zoomFactor > clientSize.w)
253 x = scroll.x / (bitmap.width * zoomFactor - clientSize.w);
254 if(bitmap.height * zoomFactor > clientSize.w)
255 y = scroll.y / (bitmap.height * zoomFactor - clientSize.h);
258 scrollArea = Size { bitmap.width * zoomFactor, bitmap.height * zoomFactor };
261 (int)(Max(0, bitmap.width * zoomFactor - clientSize.w) * x),
262 (int)(Max(0, bitmap.height * zoomFactor - clientSize.h) * y) };
271 bool OnSaveFile(const char * fileName)
276 if(bitmap.Save(fileName,
277 ((FileType *)pictureEditFileDialog.types)[pictureEditFileDialog.fileType].typeExtension, (void *) bool::true))
279 modifiedDocument = false;
295 delete bitmapNotIndexed;
299 class PictureEditColorTable : Window
302 text = $"Color Table";
303 background = formColor;
304 minClientSize = Size { 400, 400 };
308 parent = this, hotKey = escape, size = { 80 }, text = $"Close";
309 anchor = Anchor { right = 10, bottom = 10 };
310 NotifyClicked = ButtonCloseDialog;
313 void OnRedraw(Surface surface)
315 PictureEdit picture = (PictureEdit)master;
316 Bitmap bitmap = picture.bitmap;
318 for(c = 0; c < 256; c++)
320 int x = (c % 16) * 16;
321 int y = (c / 16) * 16;
322 surface.SetBackground(bitmap.palette[c]);
323 surface.Area(10 + x, 30 + y, 10 + x + 15, 30 + y + 15);
328 class ColorBox : Window
331 borderStyle = deepContour;
335 class AdjustHSV : Window
339 background = formColor;
342 replace = { 248, 100, 71 }; //Color { 26, 0, 183 };
343 target = { 207, 61, 71 };
348 this, text = $"Go", position = { 296, 104 }, isDefault = true;
350 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
352 PictureEdit picture = (PictureEdit)master;
353 Bitmap bitmap = picture.bitmap;
354 double h = 1.0f, s = 0.80f, v = 1.24f;
359 h = target.h - replace.h;
360 s = target.s / replace.s;
361 v = target.v / replace.v;
363 for(y = 0; y<bitmap.height; y++)
365 for(x = 0; x<bitmap.width; x++)
367 ColorAlpha color = ((ColorAlpha *)bitmap.picture)[y * bitmap.stride + x];
368 ColorHSV hsv = color;
369 double diffH = Abs(hsv.h/360 - replace.h/360);
370 double diffS = Abs(hsv.s - replace.s)/100.0;
371 double diffV = Abs(hsv.v - replace.v)/100.0;
372 if(diffH <= tolH && diffS <= tolS && diffV <= tolV)
378 ((ColorAlpha *)bitmap.picture)[y * bitmap.stride + x] = color;
382 picture.Update(null);
383 picture.modifiedDocument = true;
389 EditBox hBox { this, text = "H", size = { 78, 19 }, position = { 176, 80 } };
390 EditBox sBox { this, text = "S", size = { 78, 19 }, position = { 176, 120 } };
391 EditBox vBox { this, text = "V", size = { 78, 19 }, position = { 176, 160 } };
392 Label label1 { this, size = { 7, 13 }, position = { 152, 80 }, labeledWindow = hBox };
393 Label label2 { this, size = { 6, 13 }, position = { 152, 120 }, labeledWindow = sBox };
394 Label label3 { this, size = { 6, 13 }, position = { 152, 168 }, labeledWindow = vBox };
395 ColorBox original { this, position = { 10, 10 }, background = replace };
396 ColorBox result { this, position = { 10, 100 }, background = target };