From 1ab49f7d465fbd8d53a5a15702070d4be546caf8 Mon Sep 17 00:00:00 2001 From: Daniel Cheung Date: Thu, 28 Feb 2019 19:06:23 +0800 Subject: [PATCH 1/2] Completed dissolve yet to test --- ImpressionistUI.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++ impressionistUI.h | 5 +++++ 2 files changed, 54 insertions(+) diff --git a/ImpressionistUI.cpp b/ImpressionistUI.cpp index 6de6402..dbe3934 100644 --- a/ImpressionistUI.cpp +++ b/ImpressionistUI.cpp @@ -621,6 +621,38 @@ void ImpressionistUI::cb_tracer_update(Fl_Widget* o, void* v) uiPtr->m_paintView->redraw(); } +void ImpressionistUI::cb_dissolve(Fl_Widget* o, void*) +{ + auto* uiPtr = static_cast(o->user_data()); + + const auto dissolveRatio = uiPtr->m_dissolveOpacitySlider->value(); + + auto* fileName = fl_file_chooser("Open File?", "*.bmp", nullptr); + if (fileName != nullptr) { + auto width = 0; + auto height = 0; + ImageWrapper imageWrapper = { + readBMP(fileName, width, height), + { width, height } + }; + + ImageUtils::eachPixel(uiPtr->m_pDoc->m_ucPainting, {uiPtr->m_pDoc->m_nPaintWidth, uiPtr->m_pDoc->m_nPaintHeight }, [&](unsigned char* rgbArray, long x, long y) + { + auto* otherPixel = imageWrapper.getPixelPtr(x, y); + rgbArray[0] = static_cast(dissolveRatio * rgbArray[0] + (1 - dissolveRatio) * otherPixel[0]); + rgbArray[1] = static_cast(dissolveRatio * rgbArray[1] + (1 - dissolveRatio) * otherPixel[1]); + rgbArray[2] = static_cast(dissolveRatio * rgbArray[2] + (1 - dissolveRatio) * otherPixel[2]); + }); + + uiPtr->m_paintView->draw(); + } + else + { + fl_alert("File not selected!"); + } +} + + //---------------------------------- per instance functions -------------------------------------- @@ -1123,4 +1155,21 @@ ImpressionistUI::ImpressionistUI() m_tracerOpacitySlider->callback(cb_tracer_update); } m_tracerDialog->end(); + + m_dissolveDialog = new Fl_Window(320, 100, "Dissolve..."); + { + m_dissolveOpacitySlider = new Fl_Value_Slider(10, 10, 300, 20, "Original Opacity"); + m_dissolveOpacitySlider->user_data(static_cast(this)); + m_dissolveOpacitySlider->type(FL_HOR_NICE_SLIDER); + m_dissolveOpacitySlider->minimum(0.0); + m_dissolveOpacitySlider->maximum(100.0); + m_dissolveOpacitySlider->step(1.0); + m_dissolveOpacitySlider->value(20.0); + m_dissolveOpacitySlider->align(FL_ALIGN_BOTTOM); + + m_dissolveLoadImageBtn = new Fl_Button(270, 65, 100, 25, "Load Image"); + m_dissolveLoadImageBtn->user_data(static_cast(this)); + m_dissolveLoadImageBtn->callback(cb_dissolve); + } + m_dissolveDialog->end(); } diff --git a/impressionistUI.h b/impressionistUI.h index f81b146..2b020fc 100644 --- a/impressionistUI.h +++ b/impressionistUI.h @@ -78,6 +78,10 @@ class ImpressionistUI { Fl_Window* m_tracerDialog; Fl_Value_Slider* m_tracerOpacitySlider; + Fl_Window* m_dissolveDialog; + Fl_Value_Slider* m_dissolveOpacitySlider; + Fl_Button* m_dissolveLoadImageBtn; + // Member functions void setDocument(ImpressionistDoc* doc); @@ -203,6 +207,7 @@ class ImpressionistUI { static Fl_Callback cb_open_colors_dialog; static Fl_Callback cb_open_tracer_dialog; static Fl_Callback cb_tracer_update; + static Fl_Callback cb_dissolve; }; From f325becc1048dd7b168bb4cdc5fc0f90f14a3e02 Mon Sep 17 00:00:00 2001 From: Daniel Cheung Date: Thu, 28 Feb 2019 19:25:34 +0800 Subject: [PATCH 2/2] Completed Dissolve --- ImpressionistUI.cpp | 17 ++++++++++++----- impressionist.vcxproj | 2 +- impressionistUI.h | 1 + readme.md | 2 +- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/ImpressionistUI.cpp b/ImpressionistUI.cpp index b2d49c2..36542b1 100644 --- a/ImpressionistUI.cpp +++ b/ImpressionistUI.cpp @@ -621,11 +621,17 @@ void ImpressionistUI::cb_tracer_update(Fl_Widget* o, void* v) uiPtr->m_paintView->redraw(); } +void ImpressionistUI::cb_open_dissolve_dialog(Fl_Widget* o, void*) +{ + whoami(dynamic_cast(o))->m_dissolveDialog->show(); +} + + void ImpressionistUI::cb_dissolve(Fl_Widget* o, void*) { auto* uiPtr = static_cast(o->user_data()); - const auto dissolveRatio = uiPtr->m_dissolveOpacitySlider->value(); + const auto dissolveRatio = uiPtr->m_dissolveOpacitySlider->value() / 100.0; auto* fileName = fl_file_chooser("Open File?", "*.bmp", nullptr); if (fileName != nullptr) { @@ -636,7 +642,7 @@ void ImpressionistUI::cb_dissolve(Fl_Widget* o, void*) { width, height } }; - ImageUtils::eachPixel(uiPtr->m_pDoc->m_ucPainting, {uiPtr->m_pDoc->m_nPaintWidth, uiPtr->m_pDoc->m_nPaintHeight }, [&](unsigned char* rgbArray, long x, long y) + ImageUtils::eachPixel(uiPtr->m_pDoc->m_ucPainting, {uiPtr->m_pDoc->m_nPaintWidth, uiPtr->m_pDoc->m_nPaintHeight }, [&](unsigned char* rgbArray, const long x, const long y) { auto* otherPixel = imageWrapper.getPixelPtr(x, y); rgbArray[0] = static_cast(dissolveRatio * rgbArray[0] + (1 - dissolveRatio) * otherPixel[0]); @@ -644,7 +650,7 @@ void ImpressionistUI::cb_dissolve(Fl_Widget* o, void*) rgbArray[2] = static_cast(dissolveRatio * rgbArray[2] + (1 - dissolveRatio) * otherPixel[2]); }); - uiPtr->m_paintView->draw(); + uiPtr->m_paintView->redraw(); } else { @@ -785,6 +791,7 @@ Fl_Menu_Item ImpressionistUI::menuitems[] = { { "&Swap Content", FL_ALT + 's', (Fl_Callback*)ImpressionistUI::cb_swap_content }, { "&Undo", FL_ALT + 'z', (Fl_Callback*)ImpressionistUI::cb_undo }, { "Tracer...", 0, cb_open_tracer_dialog }, + { "Dissolve...", 0, cb_open_dissolve_dialog }, { "&Auto Fill", FL_ALT + 'f', (Fl_Callback*)ImpressionistUI::cb_auto_fill_menu }, { "&Load Another Img", FL_ALT + 'l', (Fl_Callback*)ImpressionistUI::cb_load_another_image }, { "&Load Mural Img", FL_ALT + 'm', (Fl_Callback*)ImpressionistUI::cb_load_mural_image }, @@ -1165,10 +1172,10 @@ ImpressionistUI::ImpressionistUI() m_dissolveOpacitySlider->minimum(0.0); m_dissolveOpacitySlider->maximum(100.0); m_dissolveOpacitySlider->step(1.0); - m_dissolveOpacitySlider->value(20.0); + m_dissolveOpacitySlider->value(50.0); m_dissolveOpacitySlider->align(FL_ALIGN_BOTTOM); - m_dissolveLoadImageBtn = new Fl_Button(270, 65, 100, 25, "Load Image"); + m_dissolveLoadImageBtn = new Fl_Button(110, 65, 100, 25, "Load Image"); m_dissolveLoadImageBtn->user_data(static_cast(this)); m_dissolveLoadImageBtn->callback(cb_dissolve); } diff --git a/impressionist.vcxproj b/impressionist.vcxproj index 751de96..b55b47c 100644 --- a/impressionist.vcxproj +++ b/impressionist.vcxproj @@ -63,7 +63,7 @@ Level3 true ProgramDatabase - local\include;%(AdditionalIncludeDirectories) + local\include;$(MSBuildProjectDirectory);%(AdditionalIncludeDirectories) WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) c:\temp\ c:\temp\impressionist.pch diff --git a/impressionistUI.h b/impressionistUI.h index 2b020fc..75aaa7d 100644 --- a/impressionistUI.h +++ b/impressionistUI.h @@ -207,6 +207,7 @@ class ImpressionistUI { static Fl_Callback cb_open_colors_dialog; static Fl_Callback cb_open_tracer_dialog; static Fl_Callback cb_tracer_update; + static Fl_Callback cb_open_dissolve_dialog; static Fl_Callback cb_dissolve; }; diff --git a/readme.md b/readme.md index 412e072..1081532 100644 --- a/readme.md +++ b/readme.md @@ -23,7 +23,7 @@ Programming project 1 of HKUST Computer Graphics course COMP4411 - [x] (1B) change color of image (change channel) - [x] **(1B)** blur brush and sharpen brush (wait for kernel brush) - [x] **(1B)** undo -- [ ] (1B) Dissolve one image into another +- [x] (1B) Dissolve one image into another - [x] (1B1W) original image overlay - [x] _(1B1W)_ mural image (load another image without resetting) - [x] (1B1W) alpha mapping brush