1- #include " cinder/app/App.h"
1+ #include " cinder/app/App.h"
22#include " cinder/app/RendererGl.h"
33#include " cinder/gl/gl.h"
4+ #include " cinder/gl/ConstantConversions.h"
45#include " cinder/Log.h"
56#include " cinder/ImageIo.h"
67#include " cinder/gl/Texture.h"
8+ #include " cinder/CinderImGui.h"
9+ #include " cinder/CanvasUi.h"
710
811using namespace ci ;
912using namespace ci ::app;
@@ -12,61 +15,186 @@ using namespace std;
1215class ImageFileBasicApp : public App {
1316 public:
1417 void setup () override ;
15- void keyDown ( KeyEvent event ) override ;
18+ void update ( ) override ;
1619 void fileDrop ( FileDropEvent event ) override ;
1720 void draw () override ;
18-
21+
22+ void openImage ( const fs::path &path );
23+ void openImageDialog ();
24+ void saveImage ();
25+ void drawGui ();
26+
1927 gl::TextureRef mTexture ;
28+ ImageSourceRef mImageSource ;
29+ fs::path mImagePath ;
30+ std::string mErrorMessage ;
31+ bool mOpenRequested = false ;
32+ bool mSaveRequested = false ;
33+ CanvasUi mCanvas ;
2034};
2135
2236void ImageFileBasicApp::setup ()
37+ {
38+ ImGui::Initialize ();
39+
40+ mCanvas .connect ( getWindow () );
41+ }
42+
43+ void ImageFileBasicApp::update ()
44+ {
45+ if ( mOpenRequested ) {
46+ mOpenRequested = false ;
47+ openImageDialog ();
48+ }
49+ if ( mSaveRequested ) {
50+ mSaveRequested = false ;
51+ saveImage ();
52+ }
53+ }
54+
55+ void ImageFileBasicApp::openImage ( const fs::path &path )
2356{
2457 try {
25- fs::path path = getOpenFilePath ( " " , ImageIo::getLoadExtensions () );
26- if ( ! path.empty () ) {
27- mTexture = gl::Texture::create ( loadImage ( path ) );
28- }
58+ mImagePath = path;
59+ mImageSource = loadImage ( path );
60+ mTexture = gl::Texture::create ( mImageSource );
61+ mCanvas .setContentBounds ( Rectf ( mTexture ->getBounds () ) );
62+ mCanvas .fitAll ();
63+ mErrorMessage .clear ();
2964 }
3065 catch ( Exception &exc ) {
3166 CI_LOG_EXCEPTION ( " failed to load image." , exc );
67+ mTexture .reset ();
68+ mImageSource .reset ();
69+ mImagePath .clear ();
70+ mErrorMessage = exc.what ();
3271 }
3372}
3473
35- void ImageFileBasicApp::keyDown ( KeyEvent event )
74+ void ImageFileBasicApp::openImageDialog ( )
3675{
37- if ( event.getChar () == ' o' ) {
38- fs::path path = getOpenFilePath ( " " , ImageIo::getLoadExtensions () );
39- if ( ! path.empty () )
40- mTexture = gl::Texture::create ( loadImage ( path ) );
41- }
42- else if ( event.getChar () == ' s' ) {
43- fs::path path = getSaveFilePath ();
44- if ( ! path.empty () ) {
45- Surface s8 ( mTexture ->createSource () );
46- writeImage ( writeFile ( path ), s8 );
47- }
76+ fs::path path = getOpenFilePath ( " " , ImageIo::getLoadExtensions () );
77+ if ( ! path.empty () ) {
78+ openImage ( path );
4879 }
4980}
5081
51- void ImageFileBasicApp::fileDrop ( FileDropEvent event )
82+ void ImageFileBasicApp::saveImage ( )
5283{
5384 try {
54- mTexture = gl::Texture::create ( loadImage ( loadFile ( event.getFile ( 0 ) ) ) );
85+ fs::path path = getSaveFilePath ( " " , ImageIo::getWriteExtensions () );
86+ if ( ! path.empty () ) {
87+ writeImage ( writeFile ( path ), mTexture ->createSource () );
88+ }
5589 }
5690 catch ( Exception &exc ) {
57- CI_LOG_EXCEPTION ( " failed to load image: " << event. getFile ( 0 ) , exc );
91+ CI_LOG_EXCEPTION ( " failed to save image. " , exc );
5892 }
5993}
6094
95+ void ImageFileBasicApp::fileDrop ( FileDropEvent event )
96+ {
97+ openImage ( event.getFile ( 0 ) );
98+ }
99+
61100void ImageFileBasicApp::draw ()
62101{
63102 gl::clear ( Color ( 0 .5f , 0 .5f , 0 .5f ) );
64- gl::enableAlphaBlending ();
65-
103+
104+ // Draw image with CanvasUi transformation
66105 if ( mTexture ) {
67- Rectf destRect = Rectf ( mTexture ->getBounds () ).getCenteredFit ( getWindowBounds (), true ).scaledCentered ( 0 .85f );
68- gl::draw ( mTexture , destRect );
106+ gl::ScopedModelMatrix scopedMatrix ( mCanvas .getModelMatrix () );
107+ gl::enableAlphaBlending ();
108+
109+ gl::draw ( mTexture , mTexture ->getBounds () );
69110 }
111+
112+ drawGui ();
113+ }
114+
115+ void ImageFileBasicApp::drawGui ()
116+ {
117+ ImGui::Begin ( " Image Info" );
118+
119+ if ( ImGui::Button ( " Open Image" ) ) {
120+ mOpenRequested = true ;
121+ }
122+
123+ ImGui::SameLine ();
124+
125+ ImGui::BeginDisabled ( ! mTexture );
126+ if ( ImGui::Button ( " Save Image" ) ) {
127+ mSaveRequested = true ;
128+ }
129+ ImGui::EndDisabled ();
130+
131+ ImGui::SameLine ();
132+
133+ ImGui::BeginDisabled ( ! mTexture );
134+ if ( ImGui::Button ( " Fit to Window" ) ) {
135+ mCanvas .setContentBounds ( Rectf ( mTexture ->getBounds () ) );
136+ mCanvas .fitAll ();
137+ }
138+ ImGui::EndDisabled ();
139+
140+ ImGui::Separator ();
141+
142+ if ( mTexture && mImageSource ) {
143+ ImGui::Text ( " File: %s" , mImagePath .filename ().string ().c_str () );
144+ ImGui::Separator ();
145+ ImGui::Text ( " Dimensions: %d x %d" , mTexture ->getWidth (), mTexture ->getHeight () );
146+ ImGui::Text ( " Texture Format: %s" , gl::constantToString ( mTexture ->getInternalFormat () ).c_str () );
147+ ImGui::Separator ();
148+
149+ // Image source information
150+ const char * colorModelStr = " Unknown" ;
151+ switch ( mImageSource ->getColorModel () ) {
152+ case ImageIo::CM_RGB: colorModelStr = " RGB" ; break ;
153+ case ImageIo::CM_GRAY: colorModelStr = " Grayscale" ; break ;
154+ default : break ;
155+ }
156+ ImGui::Text ( " Color Model: %s" , colorModelStr );
157+
158+ const char * dataTypeStr = " Unknown" ;
159+ switch ( mImageSource ->getDataType () ) {
160+ case ImageIo::UINT8: dataTypeStr = " UINT8" ; break ;
161+ case ImageIo::UINT16: dataTypeStr = " UINT16" ; break ;
162+ case ImageIo::FLOAT16: dataTypeStr = " FLOAT16" ; break ;
163+ case ImageIo::FLOAT32: dataTypeStr = " FLOAT32" ; break ;
164+ default : break ;
165+ }
166+ ImGui::Text ( " Data Type: %s" , dataTypeStr );
167+
168+ const char * channelOrderStr = " Unknown" ;
169+ switch ( mImageSource ->getChannelOrder () ) {
170+ case ImageIo::Y: channelOrderStr = " Y (Grayscale)" ; break ;
171+ case ImageIo::YA: channelOrderStr = " YA (Grayscale + Alpha)" ; break ;
172+ case ImageIo::RGB: channelOrderStr = " RGB" ; break ;
173+ case ImageIo::RGBA: channelOrderStr = " RGBA" ; break ;
174+ case ImageIo::RGBX: channelOrderStr = " RGBX" ; break ;
175+ case ImageIo::BGR: channelOrderStr = " BGR" ; break ;
176+ case ImageIo::BGRA: channelOrderStr = " BGRA" ; break ;
177+ case ImageIo::BGRX: channelOrderStr = " BGRX" ; break ;
178+ default : break ;
179+ }
180+ ImGui::Text ( " Channel Order: %s" , channelOrderStr );
181+
182+ ImGui::Text ( " Has Alpha: %s" , mImageSource ->hasAlpha () ? " Yes" : " No" );
183+ ImGui::Text ( " Premultiplied: %s" , mImageSource ->isPremultiplied () ? " Yes" : " No" );
184+ }
185+ else {
186+ ImGui::Text ( " No image loaded" );
187+ ImGui::Text ( " Click 'Open Image' or drag & drop an image file" );
188+
189+ if ( ! mErrorMessage .empty () ) {
190+ ImGui::Separator ();
191+ ImGui::PushStyleColor ( ImGuiCol_Text, ImVec4 ( 1 .0f , 0 .3f , 0 .3f , 1 .0f ) );
192+ ImGui::TextWrapped ( " Error: %s" , mErrorMessage .c_str () );
193+ ImGui::PopStyleColor ();
194+ }
195+ }
196+
197+ ImGui::End ();
70198}
71199
72200CINDER_APP ( ImageFileBasicApp, RendererGl )
0 commit comments