Im Buch spreche ich im Grafikkapitel ja ein kleines Projekt namens „Needlework8“ an, eine kleine App, mit der man aus Anfängergekritzel leicht ansprechende 8-Bit-Grafiken gestalten kann. Also praktisch ein einfaches Zeichenprogramm für Sprites mit rudimentären und speziellen Funktionen (die ich sonst leider in keiner Zeichen-App gefunden haben, sonst hätte ich mir das sparen können) wie z. B.

  • Zeichnen
    • Freihand
    • Linie
    • Umrisslinie
  • Füllung
    • Standard
    • Plastisch (3D)
    • Struktur
  • Radiergummi
  • Colorpicker
  • Lupe
  • Undo
  • Datei öffnen (to do!)
  • Datei speichern (to do!)


Der Workflow: Freihandgekritzle / Umrisslinie / Füllung (3D) / StrukturfuellungDer Workflow: Freihandgekritzle > Umrisslinie > Füllung (3D) > Strukturfüllung

Das Programm ist natürlich noch weit entfernt von Produktreife und in letzter Zeit finde ich leider auch kaum Zeit um an „Needlework8“ weiter zu arbeiten, aber ich werde es auf jeden Fall vervollständigen! Versprochen!

Bis dahin möchte ich vorab einmal den Quellcode zur Verfügung stellen, vielleicht möchte der Eine oder die Andere ja diesen erweitern oder vollenden und dann selbst in den AppStore stellen? Es genügt, wenn Sie eine neue „Single View“-App erstellen, in den beiden folgenden Kästen finden Sie die dazugehörigen Codezeilen.

Benötigt werden hierfür die üblichen Frameworks inkl. „CoreGraphics“ und „QuartzCore“, die verwendeten Grafiken und Icons können Sie hier downloaden.

Das Standardzeugs:

#import <UIKit/UIKit.h>

int main(int argc, char *argv[]) {
    
    @autoreleasepool {
        int retVal = UIApplicationMain(argc, argv, nil, nil);
        return retVal;
    }
}
#import <UIKit/UIKit.h>

@class needlework8ViewController;

@interface needlework8AppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    needlework8ViewController *viewController;
}

@property (nonatomic, strong) IBOutlet UIWindow *window;
@property (nonatomic, strong) IBOutlet needlework8ViewController *viewController;

@end
#import "needlework8AppDelegate.h"
#import "needlework8ViewController.h"

@implementation needlework8AppDelegate

@synthesize window;
@synthesize viewController;

#pragma mark -
#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application
            didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    [self.window addSubview:viewController.view];
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application {}
- (void)applicationDidEnterBackground:(UIApplication *)application {}
- (void)applicationWillEnterForeground:(UIApplication *)application {}
- (void)applicationDidBecomeActive:(UIApplication *)application {}
- (void)applicationWillTerminate:(UIApplication *)application {}

#pragma mark -
#pragma mark Memory management

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {}

@end

Der interessante Programmcode:

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>

@interface needlework8ViewController : UIViewController {
	UIView *main;
	
	UIView *canvas;
	
	UIView *colorPicker;
		UIImageView *palette;
		UIView *paletteCurrentColor;
		UIImageView *paletteColorMarker;
	
	NSMutableArray *pixel;
	UIColor *currentColor;
	UIColor *tempColor;

	// Icons
	UIButton *icon_3d;
	UIButton *icon_floodfill;
	UIButton *icon_textur;
	UIButton *icon_draw;
	UIButton *icon_line;
	UIButton *icon_outline;
	UIButton *icon_erase;
	UIButton *icon_erase_all;
	
	CGPoint alt;
	
	int paintMode;
	int lastPaintMode;
	int width;
	int height;
	
	double dragX;
	double dragY;
	double lastScale;
	
	double scale;
	double zoom;

	int colR;
	int colG;
	int colB;
	
	int paletteColMarker;
	
	int threads;
	
	NSMutableArray *maske;
	
	NSMutableArray *back;
	
}

@property (nonatomic, strong) UIView *main;

@property (nonatomic, strong) UIView *canvas;

@property (nonatomic, strong) UIView *colorPicker;
@property (nonatomic, strong) UIImageView *palette;
@property (nonatomic, strong) UIImageView *paletteColorMarker;
@property (nonatomic, strong) UIView *paletteCurrentColor;

// Icons
@property (nonatomic, strong) UIButton *icon_3d;
@property (nonatomic, strong) UIButton *icon_floodfill;
@property (nonatomic, strong) UIButton *icon_textur;
@property (nonatomic, strong) UIButton *icon_draw;
@property (nonatomic, strong) UIButton *icon_line;
@property (nonatomic, strong) UIButton *icon_outline;
@property (nonatomic, strong) UIButton *icon_erase;
@property (nonatomic, strong) UIButton *icon_erase_all;


@property (nonatomic, strong) NSMutableArray *pixel;
@property (nonatomic, strong) UIColor *currentColor;
@property (nonatomic, strong) UIColor *tempColor;
@property (nonatomic) CGPoint alt;
@property (nonatomic, strong) NSMutableArray *maske;

@property (nonatomic, strong) NSMutableArray *back;

@end
#import "needlework8ViewController.h"

@implementation needlework8ViewController

@synthesize main, canvas, colorPicker, palette, paletteColorMarker, paletteCurrentColor, pixel, currentColor, tempColor, maske, back, alt;
// Icons
@synthesize icon_3d, icon_textur, icon_floodfill, icon_draw, icon_line, icon_outline, icon_erase, icon_erase_all;


#define paint 0
#define rubber 1
#define outline 2
#define textur 3
#define fill3d 4
#define floodfill 5
#define drawline 6

#define getColorFromPixel 98
#define getColorFromPalette 99

- (void)loadView {
	
	width = 40;
	height = 60;
	scale = 1.0f;
	
	colR = 255;
	colG = 0;
	colB = 0;
	
	zoom = 7.0;
	
	paletteColMarker=128;
	
	threads = 0;
	
	paintMode=paint;

	currentColor = [[UIColor alloc] initWithRed:(238 / 255.0) green:(0 / 255.0) blue:(22 / 255.0) alpha: 1];
	
	srandom([[NSDate date] timeIntervalSince1970]);
	
	[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];	
	[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
	
	// Mainscreen
	main = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
	[main setBackgroundColor:[UIColor grayColor]];
	main.userInteractionEnabled = YES;
	main.multipleTouchEnabled = YES;
	self.view = main;
	
	// Create the Pinch Gesture Recognizer
	UIPinchGestureRecognizer *PinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(Perform_Pinch:)];
	[self.view addGestureRecognizer:PinchRecognizer];
	
	
	// Leinwand
	canvas = [[UIView alloc] initWithFrame:CGRectMake(0,0,width*scale,height*scale)];
	canvas.center = CGPointMake(160.0f, 225.0f);
	canvas.backgroundColor=[UIColor darkGrayColor];
	[main addSubview:canvas];
	
	
	// Maske + Rueckgaengig initialisieren
	maske = [[NSMutableArray alloc] init];
	back = [[NSMutableArray alloc] init];
	
	// Pixelflaeche generieren
	pixel = [[NSMutableArray alloc] init];
	for(int i = 0; i < width * height; i++) {
		CALayer *tempPixel = [[CALayer layer] init];
		[tempPixel setBounds:CGRectMake(0,0, scale, scale)];
		[tempPixel setPosition:CGPointMake(i%width*scale, i/width*scale)];
		UIColor *myColor = [UIColor clearColor];
		[tempPixel setBackgroundColor:[myColor CGColor]];
		[pixel addObject:tempPixel];
		[canvas.layer addSublayer:[pixel objectAtIndex:i]];
	}
	
	
	colorPicker = [[UIView alloc] initWithFrame:CGRectMake(0.0,0.0,320.0,480.0)];
	colorPicker.backgroundColor=[UIColor blackColor];
	colorPicker.alpha=0.0;
	[main addSubview:colorPicker];

	paletteCurrentColor = [[UIView alloc] initWithFrame:CGRectMake(10.0,10.0,300.0,90.0)];
	paletteCurrentColor.backgroundColor=currentColor;
	[colorPicker addSubview:paletteCurrentColor];
		
	palette = [[UIImageView alloc] initWithFrame:CGRectMake(0, 110, 320, 340)];
	[palette setImage:[UIImage imageNamed:@"palette.png"]];
	[colorPicker addSubview:palette];
		
	paletteColorMarker = [[UIImageView alloc] initWithFrame:CGRectMake(20*(paletteColMarker%16)-1, 110+20*(paletteColMarker/16)-1, 24, 24)];
	[paletteColorMarker setImage:[UIImage imageNamed:@"colorpicker.png"]];
	[colorPicker addSubview:paletteColorMarker];

	// grosse Icons
	{
		UIImage *i_3d = [UIImage imageNamed:@"icon_3d.png"];
		icon_3d =[[UIButton alloc]initWithFrame:CGRectMake(160,470,53,53)];
		[icon_3d setBackgroundImage:i_3d forState:UIControlStateNormal];
		[icon_3d addTarget:self action:@selector(do_3d) forControlEvents:UIControlEventTouchUpInside];
		[main addSubview:icon_3d];
		
		
		UIImage *i_textur = [UIImage imageNamed:@"icon_textur.png"];
		icon_textur =[[UIButton alloc]initWithFrame:CGRectMake(160,470,53,53)];
		[icon_textur setBackgroundImage:i_textur forState:UIControlStateNormal];
		[icon_textur addTarget:self action:@selector(do_textur) forControlEvents:UIControlEventTouchUpInside];
		[main addSubview:icon_textur];
		
		UIImage *i_floodfill = [UIImage imageNamed:@"icon_floodfill.png"];
		icon_floodfill =[[UIButton alloc]initWithFrame:CGRectMake(160,470,53,53)];
		[icon_floodfill setBackgroundImage:i_floodfill forState:UIControlStateNormal];
		//[icon_floodfill setBackgroundImage:pressedImage forState:UIControlStateHighlighted];
		//[icon_floodfill setTitle:@"Bismillah" forState:UIControlStateNormal];	
		[icon_floodfill addTarget:self action:@selector(do_floodfill) forControlEvents:UIControlEventTouchUpInside];
		[main addSubview:icon_floodfill];
		
		UIImage *i_draw = [UIImage imageNamed:@"icon_draw.png"];
		icon_draw =[[UIButton alloc]initWithFrame:CGRectMake(160,470,53,53)];
		[icon_draw setBackgroundImage:i_draw forState:UIControlStateNormal];
		[icon_draw addTarget:self action:@selector(hideAllOptions) forControlEvents:UIControlEventTouchUpInside];
		[main addSubview:icon_draw];
		
		UIImage *i_line = [UIImage imageNamed:@"icon_line.png"];
		icon_line =[[UIButton alloc]initWithFrame:CGRectMake(160,470,53,53)];
		[icon_line setBackgroundImage:i_line forState:UIControlStateNormal];
		[icon_line addTarget:self action:@selector(do_line) forControlEvents:UIControlEventTouchUpInside];
		[main addSubview:icon_line];

		UIImage *i_outline = [UIImage imageNamed:@"icon_outline.png"];
		icon_outline =[[UIButton alloc]initWithFrame:CGRectMake(160,470,53,53)];
		[icon_outline setBackgroundImage:i_outline forState:UIControlStateNormal];
		[icon_outline addTarget:self action:@selector(do_outline) forControlEvents:UIControlEventTouchUpInside];
		[main addSubview:icon_outline];
		
		UIImage *i_erase = [UIImage imageNamed:@"icon_erase.png"];
		icon_erase =[[UIButton alloc]initWithFrame:CGRectMake(160,470,53,53)];
		[icon_erase setBackgroundImage:i_erase forState:UIControlStateNormal];
		[icon_erase addTarget:self action:@selector(hideAllOptions) forControlEvents:UIControlEventTouchUpInside];
		[main addSubview:icon_erase];
		
		UIImage *i_erase_all = [UIImage imageNamed:@"icon_erase_all.png"];
		icon_erase_all =[[UIButton alloc]initWithFrame:CGRectMake(160,470,53,53)];
		[icon_erase_all setBackgroundImage:i_erase_all forState:UIControlStateNormal];
		[icon_erase_all addTarget:self action:@selector(do_new) forControlEvents:UIControlEventTouchUpInside];
		[main addSubview:icon_erase_all];
		
	}
	
	// kleine Icons (Toolbar)
	
	UIToolbar *toolbar =[[UIToolbar alloc] initWithFrame:CGRectMake(0, 450, 320, 30)];
	toolbar.barStyle = UIBarStyleBlack;
	[main addSubview:toolbar];
	
	UIBarButtonItem *button1 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_pinsel.png"] style:UIBarButtonItemStylePlain target:self action:@selector(do_paint)];
	UIBarButtonItem *button2 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_rubber.png"] style:UIBarButtonItemStylePlain target:self action:@selector(do_rubber)];	
	//UIBarButtonItem *button3 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_outline.png"] style:UIBarButtonItemStylePlain target:self action:@selector(do_outline)];
	UIBarButtonItem *button4 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_fill.png"] style:UIBarButtonItemStylePlain target:self action:@selector(do_fill)];	
	//UIBarButtonItem *button5 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_3d.png"] style:UIBarButtonItemStylePlain target:self action:@selector(do_3d)];
	
	//UIImageView *yourImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"icon_palette.png"]];
	//UIBarButtonItem *button6 = [[UIBarButtonItem alloc] initWithCustomView:yourImageView action:@selector(do_palette)];
	UIBarButtonItem *button6 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_palette.png"] style:UIBarButtonItemStylePlain target:self action:@selector(do_palette)];
	//UIBarButtonItem *button7 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_new.png"] style:UIBarButtonItemStylePlain target:self action:@selector(do_new)];
	UIBarButtonItem *button8 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_colorpicker.png"] style:UIBarButtonItemStylePlain target:self action:@selector(do_getcolor)];
	UIBarButtonItem *button9 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_zoom11.png"] style:UIBarButtonItemStylePlain target:self action:@selector(do_zoom11)];
	UIBarButtonItem *button10 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_back.png"] style:UIBarButtonItemStylePlain target:self action:@selector(do_back)];
	UIBarButtonItem *button11 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_save.png"] style:UIBarButtonItemStylePlain target:self action:@selector(do_save)];
	UIBarButtonItem *button12 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_save.png"] style:UIBarButtonItemStylePlain target:self action:@selector(do_load)];

	UIBarButtonItem *BtnSpace = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
	[toolbar setItems:[NSArray arrayWithObjects:button12,button1, button2, button4, button9, button10, BtnSpace, button8, button6, BtnSpace, button11, nil]];	

	//[UIView beginAnimations:nil context:nil];   
	//[UIView setAnimationDuration:10.0];   
	//CGAffineTransform transform = CGAffineTransformMakeScale(zoom, zoom);  
	canvas.transform = CGAffineTransformMakeScale(zoom, zoom); 
	//[UIView commitAnimations];
	
}

// ----------------------------
 // ---------------------------
 // --- BUTTON ACTION ---------
 // ---------------------------
 // ---------------------------

-(void) hideAllOptions {
	[UIView transitionWithView:self.view duration:0.25 options:UIViewAnimationOptionTransitionNone animations:^{
		icon_3d.alpha=0.0; icon_3d.center=CGPointMake(160,470);
		icon_textur.alpha=0.0; icon_textur.center=CGPointMake(160,470);
		icon_floodfill.alpha=0.0; icon_floodfill.center=CGPointMake(160,470);
		icon_draw.alpha=0.0; icon_draw.center=CGPointMake(160,470);
		icon_line.alpha=0.0; icon_line.center=CGPointMake(160,470);
		icon_outline.alpha=0.0; icon_outline.center=CGPointMake(160,470);
		icon_erase.alpha=0.0; icon_erase.center=CGPointMake(160,470);
		icon_erase_all.alpha=0.0; icon_erase_all.center=CGPointMake(160,470);
	} completion:^(BOOL finished) { }];		
}
-(void) showFillOptions {
	[UIView transitionWithView:self.view duration:0.25 options:UIViewAnimationOptionTransitionNone animations:^{
		icon_3d.alpha=1.0;
		icon_3d.center=CGPointMake(220,400);
		icon_textur.alpha=1.0;
		icon_textur.center=CGPointMake(160,400);
		icon_floodfill.alpha=1.0;
		icon_floodfill.center=CGPointMake(100,400);
	} completion:^(BOOL finished) { paintMode=floodfill; }];		
}
-(void) showDrawOptions {
	[UIView transitionWithView:self.view duration:0.25 options:UIViewAnimationOptionTransitionNone animations:^{
		icon_draw.alpha=1.0;
		icon_draw.center=CGPointMake(100,400);
		icon_line.alpha=1.0;
		icon_line.center=CGPointMake(160,400);
		icon_outline.alpha=1.0;
		icon_outline.center=CGPointMake(220,400);
	} completion:^(BOOL finished) { paintMode=paint; }];		
}
-(void) showRubberOptions {
	[UIView transitionWithView:self.view duration:0.25 options:UIViewAnimationOptionTransitionNone animations:^{
		icon_erase.alpha=1.0;
		icon_erase.center=CGPointMake(140,400);
		icon_erase_all.alpha=1.0;
		icon_erase_all.center=CGPointMake(200,400);
	} completion:^(BOOL finished) { paintMode=rubber; }];		
}
-(void) prepareBack {
	// Back-Funktion
	[back removeAllObjects];
	for (int i=0;i<width*height;i++) {
		CALayer *pix = [pixel objectAtIndex:i];
		[back addObject:[UIColor colorWithCGColor:pix.backgroundColor]];
	}
}

// Abfrage und Neustart
- (void)alertView:(UIAlertView  *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
	if (buttonIndex==1) {
		for (int p=0;p<width*height;p++) {
			CALayer *clearPix = [pixel objectAtIndex:p];
			clearPix.backgroundColor=[[UIColor clearColor] CGColor];
		}
		paintMode=paint;
		canvas.center=CGPointMake(160.0f, 225.0f);
		canvas.transform = CGAffineTransformMakeScale(7.0f, 7.0f);
	}
	else {
		paintMode=paint;
	}

}

-(void) do_new {
	[self hideAllOptions];
	[self prepareBack];
	UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Neues Pixel Artwork" message:@"Aktuelles Projekt löschen und neues Pixel Artwork beginnen?" delegate:self cancelButtonTitle:@"Abbrechen" otherButtonTitles:nil];
    [alert addButtonWithTitle:@"Ja"];
	alert.delegate=self;
    [alert show];
}

-(void) do_back {
	[self hideAllOptions];
	for (int p=0;p<width*height;p++) {
	 CALayer *backPix = [pixel objectAtIndex:p];
	 backPix.backgroundColor=[[back objectAtIndex:p] CGColor]; // ???
	 }
}

-(void) do_zoom11 {
	[self hideAllOptions];
	[UIView transitionWithView:self.view duration:0.5 options:UIViewAnimationOptionTransitionNone animations:^{canvas.transform = CGAffineTransformMakeScale(1.0f, 1.0f);canvas.center=CGPointMake(160.0,225.0);} completion:^(BOOL finished) {}];
	
}

-(void) do_paint {lastPaintMode=paintMode; paintMode=paint;[self hideAllOptions];[self showDrawOptions];}

-(void) do_line {lastPaintMode=paintMode; paintMode=drawline;[self hideAllOptions];}

-(void) do_rubber {lastPaintMode=paintMode; paintMode=rubber;[self hideAllOptions];[self showRubberOptions];}

-(void) do_outline {lastPaintMode=paintMode; paintMode=outline;[self hideAllOptions];}

-(void) do_getcolor {lastPaintMode=paintMode; paintMode=getColorFromPixel;}

-(void) do_textur {lastPaintMode=paintMode; paintMode=textur; [self hideAllOptions];}
-(void) do_3d {lastPaintMode=paintMode; paintMode=fill3d; [self hideAllOptions];}
-(void) do_floodfill {lastPaintMode=paintMode; paintMode=floodfill; [self hideAllOptions];}

-(void) do_palette {
	[self hideAllOptions];
	if (paintMode==getColorFromPalette) {
		[UIView transitionWithView:self.view duration:0.25 options:UIViewAnimationOptionTransitionNone animations:^{colorPicker.alpha=0.0;} completion:^(BOOL finished) {}];
		paintMode=lastPaintMode;
	}
	else {
		lastPaintMode=paintMode;
		[UIView transitionWithView:self.view duration:0.25 options:UIViewAnimationOptionTransitionNone animations:^{colorPicker.alpha=1.0;} completion:^(BOOL finished) {}];
		paintMode=getColorFromPalette;
	}
}	

-(void) do_fill {
	if (paintMode==getColorFromPalette) { [self hideAllOptions]; } else { [self showFillOptions]; }
}

// ----------------------------
 // ----------------------------
 // -- LOAD + SAVE ACTION -----
 // ---------------------------
 // ---------------------------

-(void) do_load {}

-(void) do_save {
	//UIGraphicsBeginImageContextWithOptions(canvas.bounds.size, NO, [[UIScreen mainScreen] scale]);
	UIGraphicsBeginImageContextWithOptions(CGSizeMake(320, 480), NO, [[UIScreen mainScreen] scale]);
	[canvas.layer renderInContext:UIGraphicsGetCurrentContext()];
	UIImage *saveImage = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();

	// PNGwrapper
	NSData* imdata = UIImagePNGRepresentation ( saveImage ); // get PNG representation
	UIImage* im2 = [UIImage imageWithData:imdata]; // wrap UIImage around PNG representation
	
	// ins Photoalbum
	UIImageWriteToSavedPhotosAlbum(im2, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}
- (void) image:(UIImage*)image didFinishSavingWithError:(NSError *)error contextInfo:(NSDictionary*)info {
	NSLog(@"Sprite has been saved.");
};


// ----------------------------
 // ---------------------------
 // --- FILL ACTION -----------
 // ---------------------------
 // ---------------------------

- (void) thread_outline:(int) x ycoord:(int)y {
	threads+=1;

	CALayer *npix = [pixel objectAtIndex:(y*width+x)];
	UIColor* nrgb = [UIColor colorWithCGColor:npix.backgroundColor];

	if ([nrgb isEqual: tempColor]) {
		[maske replaceObjectAtIndex:y*width+x withObject:@"1"];
		 npix.backgroundColor=[[UIColor whiteColor] CGColor];
		 if (y*width+x+1   <  width*height)	[self thread_outline:x+1 	ycoord:y];
		 if (y*width+x-1   >= 0)			[self thread_outline:x-1 	ycoord:y];
		 if ((y+1)*width+x <  width*height)	[self thread_outline:x 		ycoord:y+1];
		 if ((y-1)*width+x >= 0)			[self thread_outline:x 		ycoord:y-1];
	 }
	threads-=1;

	if (threads==0) {
		for (int y0=0;y0<height;y0++){
			for (int x0=0;x0<width;x0++) {
				if ([[maske objectAtIndex:y0*width+x0] isEqual:@"1"]) {
					CALayer *tpix = [pixel objectAtIndex:(y0*width+x0)];
					tpix.backgroundColor=[tempColor CGColor];
					
					UIColor* outliner=currentColor;
					if ([currentColor isEqual:tempColor]) outliner=[UIColor blackColor];
					
					if ((x0+1<width)&&([[maske objectAtIndex:y0*width+x0+1] isEqual:@"0"])) {
						CALayer *tpix = [pixel objectAtIndex:(y0*width+x0+1)];
						tpix.backgroundColor=[outliner CGColor];
					}	
					if ((x0-1>=0)&&([[maske objectAtIndex:y0*width+x0-1] isEqual:@"0"])) {
						CALayer *tpix = [pixel objectAtIndex:(y0*width+x0-1)];
						tpix.backgroundColor=[outliner CGColor];
					}	
					if ((y0+1<height)&&([[maske objectAtIndex:(y0+1)*width+x0] isEqual:@"0"])) {
						CALayer *tpix = [pixel objectAtIndex:((y0+1)*width+x0)];
						tpix.backgroundColor=[outliner CGColor];
					}	
					if ((y0-1>=0)&&([[maske objectAtIndex:(y0-1)*width+x0] isEqual:@"0"])) {
						CALayer *tpix = [pixel objectAtIndex:((y0-1)*width+x0)];
						tpix.backgroundColor=[outliner CGColor];
					}	
					
				}
			}
		}
		//paintMode=lastPaintMode;
	}
    
}

- (void) thread_fill3d:(int) x ycoord:(int)y {
	threads+=1;
	
	CALayer *curPix = [pixel objectAtIndex:(y*width+x)];
	UIColor *crgb = [UIColor colorWithCGColor:curPix.backgroundColor];
	
	if ([crgb isEqual:tempColor]) {
		[maske replaceObjectAtIndex:y*width+x withObject:@"1"];
		curPix.backgroundColor=[[UIColor whiteColor] CGColor];
		if (y*width+x+1   <  width*height)	[self thread_fill3d:x+1 	ycoord:y];
		if (y*width+x-1   >= 0)				[self thread_fill3d:x-1 	ycoord:y];
		if ((y+1)*width+x <  width*height)	[self thread_fill3d:x 		ycoord:y+1];
		if ((y-1)*width+x >= 0)				[self thread_fill3d:x 		ycoord:y-1];
	}
	threads-=1;
	
	if (threads==0) {

		const CGFloat *rgba = CGColorGetComponents( crgb.CGColor );
		
		CGFloat Y = 0.3*rgba[0] + 0.6*rgba[1] + 0.1*rgba[2];
		CGFloat U = -0.3*rgba[0] - 0.6*rgba[1] + 0.9*rgba[2];
		CGFloat V = 0.7*rgba[0] - 0.6*rgba[1] - 0.1*rgba[2];
		
		// Helligkeit erhoehen
		Y=Y+0.2f;
		CGFloat R = Y + V;
		CGFloat G = Y - 0.166f*U - 0.5*V;
		CGFloat B = Y + U;
		UIColor *light = [[UIColor alloc] initWithRed:R green:G blue:B alpha: 1];
		
		// Helligkeit ganz hoch
		Y=Y+0.2f;
		R = Y + V;
		G = Y - 0.166f*U - 0.5*V;
		B = Y + U;
		UIColor *superlight = [[UIColor alloc] initWithRed:R green:G blue:B alpha: 1];
		
		// Helligkeit mitteldunkel
		Y=Y-0.6f;
		R = Y + V;
		G = Y - 0.166f*U - 0.5*V;
		B = Y + U;
		UIColor *dark = [[UIColor alloc] initWithRed:R green:G blue:B alpha: 1];
		
		// Helligkeit dunkel
		Y=Y-0.2f;
		R = Y + V;
		G = Y - 0.166f*U - 0.5*V;
		B = Y + U;
		UIColor *superdark = [[UIColor alloc] initWithRed:R green:G blue:B alpha: 1];
		
		for (int y0=0;y0<height;y0++){
			for (int x0=0;x0<width;x0++) {
				
				if ([[maske objectAtIndex:y0*width+x0] isEqual:@"1"]) {
				
					CALayer *tpix = [pixel objectAtIndex:(y0*width+x0)];
					tpix.backgroundColor=[tempColor CGColor];
					
					if (x0==width-1) {
						tpix.backgroundColor=[superdark CGColor];	
					}
					else if (y0==height-1) {
						tpix.backgroundColor=[superdark CGColor];	
					}
					else if (x0==0) {
						tpix.backgroundColor=[superlight CGColor];	
					}
					else if (y0==0) {
						tpix.backgroundColor=[superlight CGColor];	
					}
					else if ( ([[maske objectAtIndex:(y0+1)*width+x0] isEqual:@"0"]) && ([[maske objectAtIndex:y0*width+x0+1] isEqual:@"0"]) ) {
						tpix.backgroundColor=[superdark CGColor];
					}
					else if ( ([[maske objectAtIndex:(y0-1)*width+x0] isEqual:@"0"]) && ([[maske objectAtIndex:y0*width+x0-1] isEqual:@"0"]) ){
						tpix.backgroundColor=[superlight CGColor];
					}					
					else if ([[maske objectAtIndex:(y0+1)*width+x0] isEqual:@"0"]) {
						tpix.backgroundColor=[dark CGColor];
					}
					else if ([[maske objectAtIndex:(y0-1)*width+x0] isEqual:@"0"]) {
						tpix.backgroundColor=[light CGColor];
					}					
					else if ([[maske objectAtIndex:y0*width+x0-1] isEqual:@"0"]) {
					 tpix.backgroundColor=[light CGColor];
					 }
					 else if ([[maske objectAtIndex:y0*width+x0+1] isEqual:@"0"]) {
					 tpix.backgroundColor=[dark CGColor];
					 }

					
				}
				
			}
		}
		paintMode=lastPaintMode;
	}
    
}

- (void) thread_floodfill:(int) x ycoord:(int)y {
	CALayer *npix = [pixel objectAtIndex:(y*width+x)];
	UIColor *nrgb = [UIColor colorWithCGColor:npix.backgroundColor];
	if ([nrgb isEqual:tempColor]) {
		npix.backgroundColor=[currentColor CGColor];
		if (y*width+x+1   <  width*height)	[self thread_floodfill:x+1 	ycoord:y];
		if (y*width+x-1   >= 0)				[self thread_floodfill:x-1 	ycoord:y];
		if ((y+1)*width+x <  width*height)	[self thread_floodfill:x 	ycoord:y+1];
		if ((y-1)*width+x >= 0)				[self thread_floodfill:x 	ycoord:y-1];
	}
	//paintMode=lastPaintMode;
}

- (void) thread_textur:(int) x ycoord:(int)y {
	CALayer *npix = [pixel objectAtIndex:(y*width+x)];
	UIColor *nrgb = [UIColor colorWithCGColor:npix.backgroundColor];
	
	const CGFloat *rgba = CGColorGetComponents( nrgb.CGColor );
	tempColor = [[UIColor alloc] initWithRed:rgba[0]*(1-(float)(random()%10)/40) green:rgba[1]*(1-(float)(random()%10)/40) blue:rgba[2]*(1-(float)(random()%10)/40) alpha: 1];
	
	if ([nrgb isEqual:currentColor]) {
	npix.backgroundColor=[tempColor CGColor];
		if (y*width+x+1   <  width*height)	[self thread_textur:x+1 ycoord:y];
		if (y*width+x-1   >= 0)				[self thread_textur:x-1 ycoord:y];
		if ((y+1)*width+x <  width*height)	[self thread_textur:x 	ycoord:y+1];
		if ((y-1)*width+x >= 0)				[self thread_textur:x 	ycoord:y-1];
	}
	//paintMode=lastPaintMode;
}

- (void) line:(int) x0 ycoord_alt:(int)y0 xcoord:(int)x ycoord:(int) y col:(UIColor*) col {
	if ((x0-x)*(x0-x)>(y0-y)*(y0-y)) {
		if (x0>x)
			for (int p=x;p<x0;p++) {
				int x1 = p;
				int y1 = y+(p-x)*(y-y0)/(x-x0+0.01);
				CALayer *zwischenPix = [pixel objectAtIndex:y1*width+x1];
				zwischenPix.backgroundColor=[col CGColor];
			}
		if (x0<=x)
			for (int p=x0;p<x;p++) {
				int x1 = p;
				int y1 = y+(p-x)*(y-y0)/(x-x0+0.01);
				CALayer *zwischenPix = [pixel objectAtIndex:y1*width+x1];
				zwischenPix.backgroundColor=[col CGColor];			}
	}
	else {
		if (y0>y)
			for (int p=y;p<y0;p++) {
				int y1 = p;
				int x1 = x+(p-y)*(x-x0)/(y-y0+0.01);
				CALayer *zwischenPix = [pixel objectAtIndex:y1*width+x1];
				zwischenPix.backgroundColor=[col CGColor];
			}
		if (y0<=y)
			for (int p=y0;p<y;p++) {
				int y1 = p;
				int x1 = x+(p-y)*(x-x0)/(y-y0+0.01);
				CALayer *zwischenPix = [pixel objectAtIndex:y1*width+x1];
				zwischenPix.backgroundColor=[col CGColor];
			}
	}
	
}

// ----------------------------
 // ---------------------------
 // --- GESTURES --------------
 // ---------------------------
 // ---------------------------


- (void) Perform_Pinch:(UIPinchGestureRecognizer*)Sender{
	if([(UIPinchGestureRecognizer*)Sender state] == UIGestureRecognizerStateEnded) {
		lastScale = 1.0;
		return;
	}
	CGFloat currentScale = 1.0 - (lastScale - [(UIPinchGestureRecognizer*)Sender scale]);
	CGAffineTransform currentTransform = canvas.transform;
	CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, currentScale, currentScale);
	[canvas setTransform:newTransform];
	lastScale = [(UIPinchGestureRecognizer*)Sender scale];
}

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
	[self hideAllOptions];
	
	UITouch *touch = [[event allTouches] anyObject];
	CGPoint coord = [touch locationInView:touch.view];
	
	NSSet *allTouches = [event allTouches];
	if ([allTouches count]>2) {
		UITouch *drag = [[allTouches allObjects] objectAtIndex:2];
		CGPoint dragCoord = [drag locationInView:drag.view];
		//pinchDistance=[self distanceBetweenTwoPoints:coord1 toPoint:coord2];
		dragX=dragCoord.x;
		dragY=dragCoord.y;
	}
	
	if (paintMode==paint || paintMode==rubber) alt = CGPointMake(coord.x,coord.y);	   
	
	if (paintMode == paint || paintMode == outline || paintMode == textur || paintMode == floodfill || paintMode == fill3d) { [self prepareBack]; }
	
	
	[self touchesMoved:touches withEvent:event];
}

- (CGFloat)distanceBetweenTwoPoints:(CGPoint)fromPoint toPoint:(CGPoint)toPoint {
	float x = toPoint.x - fromPoint.x;
	float y = toPoint.y - fromPoint.y;
	return sqrt(x * x + y * y);
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
	UITouch *touch = [[event allTouches] anyObject];
	CGPoint coord = [touch locationInView:touch.view];
	
	int x = coord.x/scale; // aktueller Punkt
	int y = coord.y/scale;

	int x0 = alt.x/scale; // vorhergehender Punkt
	int y0 = alt.y/scale;
	
	
	// zoom+=0.1f;
	// CGAffineTransform transform = CGAffineTransformMakeScale(zoom, zoom);  
	// canvas.transform = transform;
	
	// Gestures
	
	NSSet *allTouches = [event allTouches];
	if ([allTouches count]>2) {
		UITouch *drag = [[allTouches allObjects] objectAtIndex:2];
		CGPoint dragCoord = [drag locationInView:drag.view];

		canvas.center=CGPointMake(canvas.center.x+(dragCoord.x-dragX), canvas.center.y+(dragCoord.y-dragY));
		
		dragX=dragCoord.x;
		dragY=dragCoord.y;
	}
	
	
	// Zeichenoperationen
	
	else if ((x<width)&&(y<height)&&(x>=0)&&(y>=0)) {
		// pix = aktueller Pixel
		CALayer *pix = [pixel objectAtIndex:(y*width+x)];
		tempColor = [UIColor colorWithCGColor:pix.backgroundColor];
		
		if (paintMode == paint) {
			
			[self line:x0 ycoord_alt:y0 xcoord:x ycoord:y col:currentColor];
			//currentColor = [[UIColor alloc] initWithRed:(colR / 255.0) green:(colG / 255.0) blue:(colB / 255.0) alpha: 1];
			[pix setBackgroundColor:[currentColor CGColor]];
			alt = coord;
		}

		if (paintMode == drawline) {
			
			[self line:x0 ycoord_alt:y0 xcoord:x ycoord:y col:currentColor];
			//currentColor = [[UIColor alloc] initWithRed:(colR / 255.0) green:(colG / 255.0) blue:(colB / 255.0) alpha: 1];
			[pix setBackgroundColor:[currentColor CGColor]];
			alt = coord;
		}

		
		if (paintMode == rubber) {
			UIColor *delColor = [UIColor clearColor];
			[self line:x0 ycoord_alt:y0 xcoord:x ycoord:y col:delColor];
			[pix setBackgroundColor:[delColor CGColor]];
		}
		
		if (paintMode == outline) {
			[maske removeAllObjects];
			for (int i=0;i<width*height;i++) [maske addObject:@"0"];
			[self thread_outline:x ycoord:y];	
		}			
		
		if (paintMode == textur) {
			[self thread_textur:x ycoord:y];	
		}
		
		if (paintMode == floodfill) {
			if (![currentColor isEqual:tempColor]) {[self thread_floodfill:x ycoord:y];}	
		}
		
		if (paintMode == fill3d) {
			[maske removeAllObjects];
			for (int i=0;i<width*height;i++) [maske addObject:@"0"];
			[self thread_fill3d:x ycoord:y];	
		}
		
		if (paintMode == getColorFromPixel) {
			currentColor = tempColor;
			if (lastPaintMode==floodfill) paintMode=floodfill; else paintMode = paint;
			paletteColMarker = 0;
		}
		
		
	}
	
	if (paintMode == getColorFromPalette) {
		if (coord.y>110) {
			int cols[816]= {0,0,0,16,16,16,32,32,32,48,48,48,64,64,64,80,80,80,96,96,96,112,112,112,128,128,128,144,144,144,160,160,160,176,176,176,192,192,192,
				208,208,208,224,224,224,255,255,255,31,0,0,33,10,4,30,22,0,27,32,2,16,33,1,10,33,4,3,33,9,1,32,17,0,31,33,3,23,32,3,11,34,4,4,32,16,1,32,26,2,36,
				31,3,25,33,2,17,62,1,0,61,20,0,62,43,0,56,59,2,31,63,0,11,63,0,0,62,13,1,61,33,1,62,63,0,43,62,0,17,60,5,2,59,30,0,62,51,1,64,62,0,47,61,1,27,92,
				1,0,92,31,2,91,66,2,81,90,0,48,93,0,16,92,1,2,92,22,1,92,48,1,92,93,2,61,91,0,24,91,9,3,93,43,0,92,75,1,90,91,0,70,91,0,41,123,0,2,121,42,1,121,
				90,0,106,122,0,64,122,1,17,123,1,0,123,27,0,122,71,0,122,123,2,79,121,0,31,122,15,1,122,58,0,121,104,0,123,123,0,95,122,0,49,153,1,0,152,51,0,152,
				110,0,131,151,0,79,154,1,24,153,0,1,153,34,0,153,88,0,153,153,0,100,154,0,42,154,18,2,152,71,1,152,129,1,156,152,0,119,152,0,63,181,1,0,182,62,2,
				181,132,1,161,180,2,94,182,0,28,182,0,0,183,43,0,182,107,2,182,183,0,120,181,0,48,182,20,2,182,88,0,183,154,0,182,183,0,142,182,0,75,213,1,0,213,
				72,1,213,154,0,188,210,1,110,213,0,31,214,0,3,212,49,0,214,120,0,212,215,2,140,212,0,58,214,23,3,212,100,0,213,179,0,210,212,1,165,213,0,90,242,0,
				0,240,84,1,241,178,2,212,241,0,127,242,1,33,242,0,0,243,57,1,242,145,0,242,243,1,155,241,2,63,240,30,1,243,115,0,243,205,0,241,242,0,183,241,0,95,
				255,17,17,255,100,18,254,193,17,225,255,17,141,255,17,51,255,16,16,255,73,16,254,156,17,255,255,17,171,255,17,78,254,47,17,255,130,17,255,221,16,
				255,255,17,199,255,16,113,254,48,48,255,123,48,255,202,48,224,255,46,156,254,47,77,255,47,47,255,97,48,255,175,49,255,255,48,180,255,47,100,254,
				76,46,255,146,48,255,227,49,255,254,48,208,255,48,128,255,77,77,255,142,76,252,210,76,229,255,76,170,255,76,99,254,74,77,254,120,75,255,184,77,
				255,255,77,190,255,79,121,255,101,76,255,160,77,255,230,77,255,255,77,213,255,77,143,255,108,108,255,159,108,255,215,107,235,255,108,185,254,109,
				129,255,109,108,255,141,107,255,195,109,255,255,107,202,255,108,146,255,126,108,254,178,108,255,234,107,255,255,108,222,255,107,167,255,137,137,254,
				179,139,255,225,137,238,255,136,198,255,136,151,255,140,135,255,166,135,255,209,137,255,255,137,210,255,136,166,254,150,137,255,192,137,255,240,137,
				255,255,138,226,254,137,181,255,166,168,255,201,167,254,233,166,242,255,166,214,254,166,177,255,167,168,254,189,169,254,223,167,255,255,167,221,255,
				167,188,253,180,165,255,207,167,255,243,168,253,254,167,235,253,168,199,255,196,198,255,219,197,252,239,195,245,255,195,227,255,197,203,254,195,197,
				255,214,197,254,235,197,255,254,196,233,252,198,211,255,206,194,255,223,198,255,248,197,253,255,197,238,253,199,213,255,227,226,255,237,227,255,249,
				227,250,254,227,241,255,227,230,255,226,227,255,233,227,255,243,227,255,255,226,244,254,227,233,255,231,227,254,240,227,255,251,226,255,255,227,249,
				255,228,237};
			int x0=coord.x/20;
			int y0=(coord.y-110)/20;
			int r0=cols[y0*16*3+x0*3];
			int g0=cols[y0*16*3+x0*3+1];
			int b0=cols[y0*16*3+x0*3+2];
			currentColor = [[UIColor alloc] initWithRed:(r0 / 255.0) green:(g0 / 255.0) blue:(b0 / 255.0) alpha: 1];
	
			paletteCurrentColor.backgroundColor=currentColor;
			paletteColMarker=x0+y0*width;
			paletteColorMarker.frame=CGRectMake(x0*20-1, 110+y0*20-1,24,24);
		}
	}	

}


- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
	//UITouch *touch = [[event allTouches] anyObject];
	//CGPoint coord = [touch locationInView:touch.view];
	if (paintMode==getColorFromPalette) {
		paintMode=paint;
		[UIView transitionWithView:self.view duration:0.25 options:UIViewAnimationOptionTransitionNone animations:^{colorPicker.alpha=0.0;} completion:^(BOOL finished) {}];
	}

}


// Override to allow orientations other than the default portrait orientation.
//- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
//    // Return YES for supported orientations
//    return (interfaceOrientation == UIInterfaceOrientationPortrait);
//}


- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
	
	// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;
}



@end

Einen Kommentar schreiben

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.