1
1
using Microsoft . Win32 ;
2
2
using System ;
3
+ using System . Collections . Generic ;
3
4
using System . IO ;
4
5
using System . Runtime . InteropServices ;
5
6
using System . Windows ;
11
12
namespace PixelArtTool
12
13
{
13
14
14
- public enum DrawMode : byte
15
+ public enum BlendMode : byte
15
16
{
16
17
Default = 0 ,
17
18
Additive = 1
18
19
}
19
20
21
+ public enum ToolMode : byte
22
+ {
23
+ Draw = 0 ,
24
+ Fill = 1
25
+ }
26
+
20
27
/// <summary>
21
28
/// Interaction logic for MainWindow.xaml
22
29
/// </summary>
@@ -62,7 +69,8 @@ public partial class MainWindow : Window
62
69
WriteableBitmap [ ] undoBufferBitmap = new WriteableBitmap [ maxUndoCount ] ;
63
70
64
71
// modes
65
- DrawMode drawMode ;
72
+ BlendMode blendMode ;
73
+ ToolMode currentTool ;
66
74
67
75
public MainWindow ( )
68
76
{
@@ -327,12 +335,12 @@ void DrawPixel(int x, int y)
327
335
328
336
PixelColor draw = new PixelColor ( ) ;
329
337
330
- switch ( drawMode )
338
+ switch ( blendMode )
331
339
{
332
- case DrawMode . Default : // replace
340
+ case BlendMode . Default : // replace
333
341
draw = currentColor ;
334
342
break ;
335
- case DrawMode . Additive :
343
+ case BlendMode . Additive :
336
344
// get old color from undo buffer
337
345
var oc = GetPixelColor ( x , y , undoBufferBitmap [ currentUndoIndex ] ) ;
338
346
// mix colors ADDITIVE mode
@@ -404,7 +412,7 @@ void PickPalette(MouseEventArgs e)
404
412
405
413
406
414
// return canvas pixel color from x,y
407
- unsafe PixelColor GetPixelColor ( int x , int y )
415
+ unsafe PixelColor GetPixel ( int x , int y )
408
416
{
409
417
var pix = new PixelColor ( ) ;
410
418
byte [ ] ColorData = { 0 , 0 , 0 , 0 } ; // B G R !
@@ -464,7 +472,7 @@ void DrawingMiddleButtonDown(object sender, MouseButtonEventArgs e)
464
472
int x = ( int ) ( e . GetPosition ( drawingImage ) . X / canvasScaleX ) ;
465
473
int y = ( int ) ( e . GetPosition ( drawingImage ) . Y / canvasScaleX ) ;
466
474
467
- currentColor = GetPixelColor ( x , y ) ;
475
+ currentColor = GetPixel ( x , y ) ;
468
476
UpdateCurrentColor ( ) ;
469
477
}
470
478
}
@@ -479,18 +487,30 @@ void DrawingLeftButtonDown(object sender, MouseButtonEventArgs e)
479
487
480
488
int x = ( int ) ( e . GetPosition ( drawingImage ) . X / canvasScaleX ) ;
481
489
int y = ( int ) ( e . GetPosition ( drawingImage ) . Y / canvasScaleX ) ;
482
- DrawPixel ( x , y ) ;
483
490
484
- if ( chkOutline . IsChecked == true )
491
+
492
+ switch ( currentTool )
485
493
{
486
- UpdateOutline ( ) ;
494
+ case ToolMode . Draw :
495
+ DrawPixel ( x , y ) ;
496
+ // mirror
497
+ if ( chkMirrorX . IsChecked == true )
498
+ {
499
+ DrawPixel ( canvasResolutionX - x - 1 , y ) ;
500
+ }
501
+ break ;
502
+ case ToolMode . Fill :
503
+ FloodFill ( x , y , ( int ) currentColor . ColorBGRA ) ;
504
+ break ;
505
+ default :
506
+ break ;
487
507
}
488
508
489
- // mirror
490
- if ( chkMirrorX . IsChecked == true )
509
+ if ( chkOutline . IsChecked == true )
491
510
{
492
- DrawPixel ( canvasResolutionX - x - 1 , y ) ;
511
+ UpdateOutline ( ) ;
493
512
}
513
+
494
514
}
495
515
496
516
void DrawingMouseUp ( object sender , MouseButtonEventArgs e )
@@ -506,12 +526,23 @@ void DrawingAreaMouseMoved(object sender, MouseEventArgs e)
506
526
507
527
if ( e . LeftButton == MouseButtonState . Pressed )
508
528
{
509
- DrawPixel ( x , y ) ;
510
- // mirror
511
- if ( chkMirrorX . IsChecked == true )
529
+ switch ( currentTool )
512
530
{
513
- DrawPixel ( canvasResolutionX - x - 1 , y ) ;
531
+ case ToolMode . Draw :
532
+ DrawPixel ( x , y ) ;
533
+ // mirror
534
+ if ( chkMirrorX . IsChecked == true )
535
+ {
536
+ DrawPixel ( canvasResolutionX - x - 1 , y ) ;
537
+ }
538
+ break ;
539
+ case ToolMode . Fill :
540
+ FloodFill ( x , y , ( int ) currentColor . ColorBGRA ) ;
541
+ break ;
542
+ default :
543
+ break ;
514
544
}
545
+
515
546
}
516
547
else if ( e . RightButton == MouseButtonState . Pressed )
517
548
{
@@ -524,7 +555,7 @@ void DrawingAreaMouseMoved(object sender, MouseEventArgs e)
524
555
}
525
556
else if ( e . MiddleButton == MouseButtonState . Pressed )
526
557
{
527
- currentColor = GetPixelColor ( x , y ) ;
558
+ currentColor = GetPixel ( x , y ) ;
528
559
}
529
560
530
561
ShowMousePos ( x , y ) ;
@@ -544,7 +575,7 @@ void ShowMousePos(int x, int y)
544
575
545
576
void ShowMousePixelColor ( int x , int y )
546
577
{
547
- var col = GetPixelColor ( x , y ) ;
578
+ var col = GetPixel ( x , y ) ;
548
579
//lblPixelColor.Content = palette[currentColorIndex].Red + "," + palette[currentColorIndex].Green + "," + palette[currentColorIndex].Blue + "," + palette[currentColorIndex].Alpha;
549
580
lblPixelColor . Content = col . Red + "," + col . Green + "," + col . Blue + "," + col . Alpha ;
550
581
}
@@ -638,7 +669,7 @@ private void OnUndoButtonDown(object sender, RoutedEventArgs e)
638
669
private void OnModeSelectionChanged ( object sender , SelectionChangedEventArgs e )
639
670
{
640
671
var s = sender as ComboBox ;
641
- drawMode = ( DrawMode ) s . SelectedIndex ;
672
+ blendMode = ( BlendMode ) s . SelectedIndex ;
642
673
}
643
674
644
675
bool leftShiftDown = false ;
@@ -694,6 +725,68 @@ public void CanExecute_Undo(object sender, CanExecuteRoutedEventArgs e)
694
725
e . CanExecute = true ;
695
726
}
696
727
728
+ void FloodFill ( int x , int y , int fillColor )
729
+ {
730
+ // get hit color pixel
731
+ var hitColor = GetPixel ( x , y ) ;
732
+
733
+ // if same as current color, exit
734
+ if ( hitColor . ColorBGRA == fillColor ) return ;
735
+
736
+ SetPixel ( canvasBitmap , x , y , ( int ) hitColor . ColorBGRA ) ;
737
+
738
+ List < int > ptsx = new List < int > ( ) ;
739
+ ptsx . Add ( x ) ;
740
+ List < int > ptsy = new List < int > ( ) ;
741
+ ptsy . Add ( y ) ;
742
+
743
+ int maxLoop = canvasResolutionX * canvasResolutionY + canvasResolutionX ;
744
+ while ( ptsx . Count > 0 && maxLoop > 0 )
745
+ {
746
+ maxLoop -- ;
747
+
748
+ if ( ptsx [ 0 ] - 1 >= 0 )
749
+ {
750
+ if ( GetPixel ( ptsx [ 0 ] - 1 , ptsy [ 0 ] ) . ColorBGRA == hitColor . ColorBGRA )
751
+ {
752
+ ptsx . Add ( ptsx [ 0 ] - 1 ) ; ptsy . Add ( ptsy [ 0 ] ) ;
753
+ SetPixel ( canvasBitmap , ptsx [ 0 ] - 1 , ptsy [ 0 ] , fillColor ) ;
754
+ }
755
+ }
756
+
757
+ if ( ptsy [ 0 ] - 1 >= 0 )
758
+ {
759
+ if ( GetPixel ( ptsx [ 0 ] , ptsy [ 0 ] - 1 ) . ColorBGRA == hitColor . ColorBGRA )
760
+ {
761
+ ptsx . Add ( ptsx [ 0 ] ) ; ptsy . Add ( ptsy [ 0 ] - 1 ) ;
762
+ SetPixel ( canvasBitmap , ptsx [ 0 ] , ptsy [ 0 ] - 1 , fillColor ) ;
763
+ }
764
+ }
765
+
766
+ if ( ptsx [ 0 ] + 1 < canvasResolutionX )
767
+ {
768
+ if ( GetPixel ( ptsx [ 0 ] + 1 , ptsy [ 0 ] ) . ColorBGRA == hitColor . ColorBGRA )
769
+ {
770
+ ptsx . Add ( ptsx [ 0 ] + 1 ) ; ptsy . Add ( ptsy [ 0 ] ) ;
771
+ SetPixel ( canvasBitmap , ptsx [ 0 ] + 1 , ptsy [ 0 ] , fillColor ) ;
772
+ }
773
+ }
774
+
775
+ if ( ptsy [ 0 ] + 1 < canvasResolutionY )
776
+ {
777
+ if ( GetPixel ( ptsx [ 0 ] , ptsy [ 0 ] + 1 ) . ColorBGRA == hitColor . ColorBGRA )
778
+ {
779
+ ptsx . Add ( ptsx [ 0 ] ) ; ptsy . Add ( ptsy [ 0 ] + 1 ) ;
780
+ SetPixel ( canvasBitmap , ptsx [ 0 ] , ptsy [ 0 ] + 1 , fillColor ) ;
781
+ }
782
+ }
783
+ ptsx . RemoveAt ( 0 ) ;
784
+ ptsy . RemoveAt ( 0 ) ;
785
+ } // while can floodfill
786
+
787
+ } // floodfill
788
+
789
+
697
790
void DrawBackgroundGrid ( )
698
791
{
699
792
PixelColor c = new PixelColor ( ) ;
@@ -811,5 +904,11 @@ int Repeat(int val, int max)
811
904
return result ;
812
905
}
813
906
907
+ private void OnToolChanged ( object sender , RoutedEventArgs e )
908
+ {
909
+ string tag = ( string ) ( ( RadioButton ) sender ) . Tag ;
910
+ Enum . TryParse ( tag , out currentTool ) ;
911
+ }
912
+
814
913
} // class
815
914
} // namespace
0 commit comments