@@ -337,6 +337,10 @@ def undo_operation():
337337 st .session_state .history_index -= 1
338338 st .session_state .processed_image = st .session_state .operation_history [st .session_state .history_index ]['image' ]
339339 return True
340+ elif st .session_state .history_index == 0 :
341+ st .session_state .history_index -= 1
342+ st .session_state .processed_image = None
343+ return True
340344 return False
341345
342346def redo_operation ():
@@ -378,6 +382,43 @@ def toggle_favorite(operation_name):
378382 }
379383}
380384
385+ def apply_preset_logic (img , preset_name ):
386+ # Ensure correct shape and copy
387+ result = img .copy ()
388+ if len (result .shape ) == 2 :
389+ result = cv2 .cvtColor (result , cv2 .COLOR_GRAY2RGB )
390+
391+ if preset_name == "📸 Portrait Enhancement" :
392+ result = cv2 .convertScaleAbs (result , alpha = 1.15 , beta = 20 )
393+ result = cv2 .GaussianBlur (result , (3 , 3 ), 0 )
394+ elif preset_name == "🌆 Landscape Boost" :
395+ hsv = cv2 .cvtColor (result , cv2 .COLOR_RGB2HSV )
396+ hsv [:,:,1 ] = cv2 .add (hsv [:,:,1 ], 30 )
397+ result = cv2 .cvtColor (hsv , cv2 .COLOR_HSV2RGB )
398+ result = cv2 .convertScaleAbs (result , alpha = 1.2 , beta = 0 )
399+ kernel_sharp = np .array ([[0 ,- 1 ,0 ], [- 1 ,5 ,- 1 ], [0 ,- 1 ,0 ]])
400+ result = cv2 .filter2D (result , - 1 , kernel_sharp )
401+ elif preset_name == "🎨 Vintage Film" :
402+ kernel_sepia = np .array ([[0.272 , 0.534 , 0.131 ],
403+ [0.349 , 0.686 , 0.168 ],
404+ [0.393 , 0.769 , 0.189 ]])
405+ result = cv2 .transform (result , kernel_sepia )
406+ result = cv2 .convertScaleAbs (result , alpha = 1.0 , beta = - 10 )
407+ elif preset_name == "✨ Social Media" :
408+ result = cv2 .convertScaleAbs (result , alpha = 1.0 , beta = 15 )
409+ hsv = cv2 .cvtColor (result , cv2 .COLOR_RGB2HSV )
410+ hsv [:,:,1 ] = cv2 .add (hsv [:,:,1 ], 20 )
411+ result = cv2 .cvtColor (hsv , cv2 .COLOR_HSV2RGB )
412+ kernel_sharp = np .array ([[0 ,- 1 ,0 ], [- 1 ,5 ,- 1 ], [0 ,- 1 ,0 ]])
413+ result = cv2 .filter2D (result , - 1 , kernel_sharp )
414+ elif preset_name == "🖤 Dramatic B&W" :
415+ result = cv2 .cvtColor (result , cv2 .COLOR_RGB2GRAY )
416+ result = cv2 .cvtColor (result , cv2 .COLOR_GRAY2RGB )
417+ result = cv2 .convertScaleAbs (result , alpha = 1.5 , beta = 0 )
418+ kernel_sharp = np .array ([[0 ,- 1 ,0 ], [- 1 ,5 ,- 1 ], [0 ,- 1 ,0 ]])
419+ result = cv2 .filter2D (result , - 1 , kernel_sharp )
420+ return result
421+
381422# Enhanced app header
382423st .markdown ('<h1 class="main-header">🖼️ Image Enhancer Pro</h1>' , unsafe_allow_html = True )
383424st .markdown ('<p class="main-subtitle">Transform your images with professional-grade processing tools | Version 2.0</p>' , unsafe_allow_html = True )
@@ -424,7 +465,10 @@ def toggle_favorite(operation_name):
424465
425466 # Display image information
426467 image = Image .open (uploaded_file )
427- img_np = np .array (image )
468+ if st .session_state .processed_image is not None :
469+ img_np = st .session_state .processed_image
470+ else :
471+ img_np = np .array (image )
428472
429473 st .markdown ("### 📊 Image Information" )
430474
@@ -458,7 +502,7 @@ def toggle_favorite(operation_name):
458502 # Preview
459503 st .markdown ("### 👁️ Preview" )
460504 st .markdown ('<div class="image-container">' , unsafe_allow_html = True )
461- st .image (img_np , use_container_width = True )
505+ st .image (img_np , width = "stretch" )
462506 st .markdown ('</div>' , unsafe_allow_html = True )
463507
464508 # Quick Presets Section
@@ -472,22 +516,26 @@ def toggle_favorite(operation_name):
472516 st .markdown ("**Steps:**" )
473517 for op in preset_data ['operations' ]:
474518 st .markdown (f"• { op } " )
475- if st .button (f"Apply { preset_name } " , key = f"preset_{ preset_name } " , use_container_width = True ):
476- st .info (f"💡 { preset_name } preset selected! Apply operations in the tabs below." )
519+ if st .button (f"Apply { preset_name } " , key = f"preset_{ preset_name } " , width = "stretch" ):
520+ processed_img = apply_preset_logic (img_np , preset_name )
521+ st .session_state .processed_image = processed_img
522+ add_to_history (f"Preset: { preset_name } " , processed_img .copy (), {"operation" : preset_name })
523+ st .success (f"✓ { preset_name } applied successfully!" )
524+ st .rerun ()
477525
478526 # Operation History and Undo/Redo
479527 st .markdown ("---" )
480528 st .markdown ("### 📜 Operation History" )
481529
482530 col_undo , col_redo = st .columns (2 )
483531 with col_undo :
484- if st .button ("⬅️ Undo" , use_container_width = True , disabled = st .session_state .history_index <= 0 , help = "Undo last operation (Ctrl+Z)" ):
532+ if st .button ("⬅️ Undo" , width = "stretch" , disabled = st .session_state .history_index < 0 , help = "Undo last operation (Ctrl+Z)" ):
485533 if undo_operation ():
486534 st .success ("✓ Undone" )
487535 st .rerun ()
488536
489537 with col_redo :
490- if st .button ("➡️ Redo" , use_container_width = True , disabled = st .session_state .history_index >= len (st .session_state .operation_history ) - 1 , help = "Redo operation (Ctrl+Y)" ):
538+ if st .button ("➡️ Redo" , width = "stretch" , disabled = st .session_state .history_index >= len (st .session_state .operation_history ) - 1 , help = "Redo operation (Ctrl+Y)" ):
491539 if redo_operation ():
492540 st .success ("✓ Redone" )
493541 st .rerun ()
@@ -515,7 +563,7 @@ def toggle_favorite(operation_name):
515563
516564 # Help and Keyboard Shortcuts
517565 st .markdown ("---" )
518- if st .button ("❓ Help & Shortcuts" , use_container_width = True ):
566+ if st .button ("❓ Help & Shortcuts" , width = "stretch" ):
519567 st .session_state .show_help = not st .session_state .show_help
520568
521569 # Options
@@ -527,7 +575,7 @@ def toggle_favorite(operation_name):
527575 help = "Display original and processed images side-by-side"
528576 )
529577
530- if st .button ("🔄 Reset All" , use_container_width = True ):
578+ if st .button ("🔄 Reset All" , width = "stretch" ):
531579 st .session_state .processed_image = None
532580 st .rerun ()
533581
@@ -563,8 +611,29 @@ def toggle_favorite(operation_name):
563611 """ , unsafe_allow_html = True )
564612
565613 image = Image .open (uploaded_file )
566- img_np = np .array (image )
567- gray = cv2 .cvtColor (img_np , cv2 .COLOR_RGB2GRAY )
614+ original_img_np = np .array (image )
615+
616+ if st .session_state .processed_image is not None :
617+ img_np = st .session_state .processed_image
618+ else :
619+ img_np = original_img_np
620+
621+ # Show comparison mode before the tabs if activated
622+ if st .session_state .comparison_mode and st .session_state .processed_image is not None :
623+ st .markdown ('<h3 class="sub-header">🔍 Comparison View</h3>' , unsafe_allow_html = True )
624+ comp_col1 , comp_col2 = st .columns (2 )
625+ with comp_col1 :
626+ st .markdown ('**Original Image**' )
627+ st .image (original_img_np , width = "stretch" )
628+ with comp_col2 :
629+ st .markdown ('**Processed Image**' )
630+ st .image (img_np , width = "stretch" )
631+ st .markdown ('---' )
632+
633+ if len (img_np .shape ) == 2 :
634+ gray = img_np
635+ else :
636+ gray = cv2 .cvtColor (img_np , cv2 .COLOR_RGB2GRAY )
568637 kernel = np .ones ((3 , 3 ), np .uint8 )
569638
570639 # Create tabs for different categories of operations
@@ -713,18 +782,18 @@ def toggle_favorite(operation_name):
713782 with col2 :
714783 if result is not None :
715784 with st .spinner ('🎨 Processing image...' ):
716- st .image (result , caption = f"Result: { basic_op } " , use_container_width = True )
785+ st .image (result , caption = f"Result: { basic_op } " , width = "stretch" )
717786
718787 # Action buttons with progress feedback
719788 btn_col1 , btn_col2 = st .columns (2 )
720789 with btn_col1 :
721- if st .button ("✅ Apply This Result" , key = f"apply_basic_{ basic_op } " , use_container_width = True , help = "Save this result to continue editing" ):
790+ if st .button ("✅ Apply This Result" , key = f"apply_basic_{ basic_op } " , width = "stretch" , help = "Save this result to continue editing" ):
722791 st .session_state .processed_image = result
723792 add_to_history (f"Basic: { basic_op } " , result .copy (), {"operation" : basic_op })
724793 st .success (f"✓ { basic_op } applied!" )
725794 st .balloons ()
726795 with btn_col2 :
727- if st .button ("🔄 Reset to Original" , key = f"reset_basic_{ basic_op } " , use_container_width = True , help = "Discard changes and start over" ):
796+ if st .button ("🔄 Reset to Original" , key = f"reset_basic_{ basic_op } " , width = "stretch" , help = "Discard changes and start over" ):
728797 st .session_state .processed_image = None
729798 st .session_state .operation_history = []
730799 st .session_state .history_index = - 1
@@ -883,17 +952,17 @@ def toggle_favorite(operation_name):
883952 with col2 :
884953 if result is not None :
885954 with st .spinner ('🎨 Processing image...' ):
886- st .image (result , caption = f"Result: { color_op } " , use_container_width = True )
955+ st .image (result , caption = f"Result: { color_op } " , width = "stretch" )
887956
888957 btn_col1 , btn_col2 = st .columns (2 )
889958 with btn_col1 :
890- if st .button ("✅ Apply This Result" , key = f"apply_color_{ color_op } " , use_container_width = True , help = "Save this result to continue editing" ):
959+ if st .button ("✅ Apply This Result" , key = f"apply_color_{ color_op } " , width = "stretch" , help = "Save this result to continue editing" ):
891960 st .session_state .processed_image = result
892961 add_to_history (f"Color: { color_op } " , result .copy (), {"operation" : color_op })
893962 st .success (f"✓ { color_op } applied!" )
894963 st .balloons ()
895964 with btn_col2 :
896- if st .button ("🔄 Reset to Original" , key = f"reset_color_{ color_op } " , use_container_width = True , help = "Discard changes and start over" ):
965+ if st .button ("🔄 Reset to Original" , key = f"reset_color_{ color_op } " , width = "stretch" , help = "Discard changes and start over" ):
897966 st .session_state .processed_image = None
898967 st .session_state .operation_history = []
899968 st .session_state .history_index = - 1
@@ -1013,17 +1082,17 @@ def toggle_favorite(operation_name):
10131082 with col2 :
10141083 if result is not None :
10151084 with st .spinner ('🔍 Processing image...' ):
1016- st .image (result , caption = f"Result: { edge_op } " , use_container_width = True )
1085+ st .image (result , caption = f"Result: { edge_op } " , width = "stretch" )
10171086
10181087 btn_col1 , btn_col2 = st .columns (2 )
10191088 with btn_col1 :
1020- if st .button ("✅ Apply This Result" , key = f"apply_edge_{ edge_op } " , use_container_width = True , help = "Save this result to continue editing" ):
1089+ if st .button ("✅ Apply This Result" , key = f"apply_edge_{ edge_op } " , width = "stretch" , help = "Save this result to continue editing" ):
10211090 st .session_state .processed_image = result
10221091 add_to_history (f"Edge: { edge_op } " , result .copy (), {"operation" : edge_op })
10231092 st .success (f"✓ { edge_op } applied!" )
10241093 st .balloons ()
10251094 with btn_col2 :
1026- if st .button ("🔄 Reset to Original" , key = f"reset_edge_{ edge_op } " , use_container_width = True , help = "Discard changes and start over" ):
1095+ if st .button ("🔄 Reset to Original" , key = f"reset_edge_{ edge_op } " , width = "stretch" , help = "Discard changes and start over" ):
10271096 st .session_state .processed_image = None
10281097 st .session_state .operation_history = []
10291098 st .session_state .history_index = - 1
@@ -1171,17 +1240,17 @@ def toggle_favorite(operation_name):
11711240 with col2 :
11721241 if result is not None :
11731242 with st .spinner ('📐 Processing image...' ):
1174- st .image (result , caption = f"Result: { morph_op } " , use_container_width = True )
1243+ st .image (result , caption = f"Result: { morph_op } " , width = "stretch" )
11751244
11761245 btn_col1 , btn_col2 = st .columns (2 )
11771246 with btn_col1 :
1178- if st .button ("✅ Apply This Result" , key = f"apply_morph_{ morph_op } " , use_container_width = True , help = "Save this result to continue editing" ):
1247+ if st .button ("✅ Apply This Result" , key = f"apply_morph_{ morph_op } " , width = "stretch" , help = "Save this result to continue editing" ):
11791248 st .session_state .processed_image = result
11801249 add_to_history (f"Morph: { morph_op } " , result .copy (), {"operation" : morph_op })
11811250 st .success (f"✓ { morph_op } applied!" )
11821251 st .balloons ()
11831252 with btn_col2 :
1184- if st .button ("🔄 Reset to Original" , key = f"reset_morph_{ morph_op } " , use_container_width = True , help = "Discard changes and start over" ):
1253+ if st .button ("🔄 Reset to Original" , key = f"reset_morph_{ morph_op } " , width = "stretch" , help = "Discard changes and start over" ):
11851254 st .session_state .processed_image = None
11861255 st .session_state .operation_history = []
11871256 st .session_state .history_index = - 1
@@ -1417,17 +1486,17 @@ def toggle_favorite(operation_name):
14171486 with col2 :
14181487 if result is not None :
14191488 with st .spinner ('✨ Processing image...' ):
1420- st .image (result , caption = f"Result: { effect_op } " , use_container_width = True )
1489+ st .image (result , caption = f"Result: { effect_op } " , width = "stretch" )
14211490
14221491 btn_col1 , btn_col2 = st .columns (2 )
14231492 with btn_col1 :
1424- if st .button ("✅ Apply This Result" , key = f"apply_effect_{ effect_op } " , use_container_width = True , help = "Save this result to continue editing" ):
1493+ if st .button ("✅ Apply This Result" , key = f"apply_effect_{ effect_op } " , width = "stretch" , help = "Save this result to continue editing" ):
14251494 st .session_state .processed_image = result
14261495 add_to_history (f"Effect: { effect_op } " , result .copy (), {"operation" : effect_op })
14271496 st .success (f"✓ { effect_op } applied!" )
14281497 st .balloons ()
14291498 with btn_col2 :
1430- if st .button ("🔄 Reset to Original" , key = f"reset_effect_{ effect_op } " , use_container_width = True , help = "Discard changes and start over" ):
1499+ if st .button ("🔄 Reset to Original" , key = f"reset_effect_{ effect_op } " , width = "stretch" , help = "Discard changes and start over" ):
14311500 st .session_state .processed_image = None
14321501 st .session_state .operation_history = []
14331502 st .session_state .history_index = - 1
@@ -1459,7 +1528,7 @@ def toggle_favorite(operation_name):
14591528 data = buf_png .getvalue (),
14601529 file_name = f"processed_{ datetime .now ().strftime ('%Y%m%d_%H%M%S' )} .png" ,
14611530 mime = "image/png" ,
1462- use_container_width = True
1531+ width = "stretch"
14631532 )
14641533
14651534 with col2 :
@@ -1474,11 +1543,11 @@ def toggle_favorite(operation_name):
14741543 data = buf_jpg .getvalue (),
14751544 file_name = f"processed_{ datetime .now ().strftime ('%Y%m%d_%H%M%S' )} .jpg" ,
14761545 mime = "image/jpeg" ,
1477- use_container_width = True
1546+ width = "stretch"
14781547 )
14791548
14801549 with col3 :
1481- if st .button ("🗑️ Clear Result" , use_container_width = True ):
1550+ if st .button ("🗑️ Clear Result" , width = "stretch" ):
14821551 st .session_state .processed_image = None
14831552 st .rerun ()
14841553else :
0 commit comments