Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 397 lines (354 sloc) 13.999 kB
d8d6de5 @kgn initial commit of working mac example
authored
1 //
2 // KGNoise.m
c76dd50 @kgn adding example iOS app
authored
3 // KGNoise
d8d6de5 @kgn initial commit of working mac example
authored
4 //
5 // Created by David Keegan on 9/11/12.
6 // Copyright (c) 2012 David Keegan. All rights reserved.
7 //
8
9 #import "KGNoise.h"
10
3a9cfe9 rename the kImageSize const
Laurin authored
11 static NSUInteger const kKGNoiseImageSize = 128;
8859b94 @kgn Adding color categories: #2
authored
12
ad2d559 @kgn Removed rand and srand fix #8
authored
13 NSInteger kgnoise_rseed = 115;
14 static inline NSInteger kgnoise_rand(){
15 return (kgnoise_rseed = (kgnoise_rseed * 214013 + 2531011) & ((1U << 31) - 1)) >> 16;
16 }
8859b94 @kgn Adding color categories: #2
authored
17
6f89947 @kgn adding KGNoiseLinearGradientView and KGNoiseRadialGradientView closes #5
authored
18 #if TARGET_OS_IPHONE
6ac4428 static inline instead of duplicate method declaration
Laurin authored
19 static inline CGFloat *gradientComponentsForColors(UIColor *color1, UIColor *color2){
6f89947 @kgn adding KGNoiseLinearGradientView and KGNoiseRadialGradientView closes #5
authored
20 #else
6ac4428 static inline instead of duplicate method declaration
Laurin authored
21 static inline CGFloat *gradientComponentsForColors(NSColor *color1, NSColor *color2){
6f89947 @kgn adding KGNoiseLinearGradientView and KGNoiseRadialGradientView closes #5
authored
22 #endif
cf8fd37 @audun Add explicit type cast and curly braces to appease compiler
audun authored
23 CGFloat *components = (CGFloat *)malloc(8*sizeof(CGFloat));
6f89947 @kgn adding KGNoiseLinearGradientView and KGNoiseRadialGradientView closes #5
authored
24 const CGFloat *alternateBackgroundComponents = CGColorGetComponents([color1 CGColor]);
25 if(CGColorGetNumberOfComponents([color1 CGColor]) == 2){
26 components[0] = alternateBackgroundComponents[0];
27 components[1] = alternateBackgroundComponents[0];
28 components[2] = alternateBackgroundComponents[0];
29 components[3] = alternateBackgroundComponents[1];
30 }else{
31 components[0] = alternateBackgroundComponents[0];
32 components[1] = alternateBackgroundComponents[1];
33 components[2] = alternateBackgroundComponents[2];
34 components[3] = alternateBackgroundComponents[3];
35 }
36
37 const CGFloat *backgroundComponents = CGColorGetComponents([color2 CGColor]);
38 if(CGColorGetNumberOfComponents([color2 CGColor]) == 2){
39 components[4] = backgroundComponents[0];
40 components[5] = backgroundComponents[0];
41 components[6] = backgroundComponents[0];
42 components[7] = backgroundComponents[1];
43 }else{
44 components[4] = backgroundComponents[0];
45 components[5] = backgroundComponents[1];
46 components[6] = backgroundComponents[2];
47 components[7] = backgroundComponents[3];
48 }
49 return components;
50 }
51
52 #pragma mark - KGNoise
53
d8d6de5 @kgn initial commit of working mac example
authored
54 @implementation KGNoise
55
56 + (void)drawNoiseWithOpacity:(CGFloat)opacity{
57 [self drawNoiseWithOpacity:opacity andBlendMode:kCGBlendModeScreen];
58 }
59
60 + (void)drawNoiseWithOpacity:(CGFloat)opacity andBlendMode:(CGBlendMode)blendMode{
61 static CGImageRef noiseImageRef = nil;
62 static dispatch_once_t oncePredicate;
63 dispatch_once(&oncePredicate, ^{
3a9cfe9 rename the kImageSize const
Laurin authored
64 NSUInteger width = kKGNoiseImageSize, height = width;
d8d6de5 @kgn initial commit of working mac example
authored
65 NSUInteger size = width*height;
76c624f @raymondjavaxx Rename "rgba" to "bitmapData"
raymondjavaxx authored
66 char *bitmapData = (char *)malloc(size);
67 for(NSUInteger i=0; i < size; ++i){
319c335 @rastersize Fix implicit loss of precision to be explicit.
rastersize authored
68 bitmapData[i] = (char)(kgnoise_rand()%256);
76c624f @raymondjavaxx Rename "rgba" to "bitmapData"
raymondjavaxx authored
69 }
d8d6de5 @kgn initial commit of working mac example
authored
70 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
71 CGContextRef bitmapContext =
1c908f4 @rastersize Squelch implicit conversion as the type is OK according to the docs.
rastersize authored
72 CGBitmapContextCreate(bitmapData, width, height, 8, width, colorSpace, (CGBitmapInfo)kCGImageAlphaNone);
d8d6de5 @kgn initial commit of working mac example
authored
73 CFRelease(colorSpace);
74 noiseImageRef = CGBitmapContextCreateImage(bitmapContext);
75 CFRelease(bitmapContext);
76c624f @raymondjavaxx Rename "rgba" to "bitmapData"
raymondjavaxx authored
76 free(bitmapData);
d8d6de5 @kgn initial commit of working mac example
authored
77 });
78
79 #if TARGET_OS_IPHONE
80 CGContextRef context = UIGraphicsGetCurrentContext();
81 #else
82 CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
83 #endif
84
85 CGContextSaveGState(context);
86 CGContextSetAlpha(context, opacity);
87 CGContextSetBlendMode(context, blendMode);
88
89 #if TARGET_OS_IPHONE
90 if([[UIScreen mainScreen] respondsToSelector:@selector(scale)]){
91 CGFloat scaleFactor = [[UIScreen mainScreen] scale];
92 CGContextScaleCTM(context, 1/scaleFactor, 1/scaleFactor);
93 }
94 #else
95 if([[NSScreen mainScreen] respondsToSelector:@selector(backingScaleFactor)]){
96 CGFloat scaleFactor = [[NSScreen mainScreen] backingScaleFactor];
97 CGContextScaleCTM(context, 1/scaleFactor, 1/scaleFactor);
98 }
99 #endif
100
e39374c @kgn Updated CGRect declaration
authored
101 CGRect imageRect = {.size={(CGFloat)CGImageGetWidth(noiseImageRef), (CGFloat)CGImageGetHeight(noiseImageRef)}};
d8d6de5 @kgn initial commit of working mac example
authored
102 CGContextDrawTiledImage(context, imageRect, noiseImageRef);
103 CGContextRestoreGState(context);
104 }
105
106 @end
107
8859b94 @kgn Adding color categories: #2
authored
108 #pragma mark - KGNoise Color
109
110 #if TARGET_OS_IPHONE
111 @implementation UIColor(KGNoise)
112 - (UIColor *)colorWithNoiseWithOpacity:(CGFloat)opacity{
113 return [self colorWithNoiseWithOpacity:opacity andBlendMode:kCGBlendModeScreen];
114 }
115 - (UIColor *)colorWithNoiseWithOpacity:(CGFloat)opacity andBlendMode:(CGBlendMode)blendMode{
e39374c @kgn Updated CGRect declaration
authored
116 CGRect rect = {.size={kKGNoiseImageSize, kKGNoiseImageSize}};
8859b94 @kgn Adding color categories: #2
authored
117 UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0.0f);
118 CGContextRef context = UIGraphicsGetCurrentContext();
119 [self setFill]; CGContextFillRect(context, rect);
120 [KGNoise drawNoiseWithOpacity:opacity andBlendMode:blendMode];
121 UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
122 UIGraphicsEndImageContext();
123 return [UIColor colorWithPatternImage:image];
124 }
125 @end
126 #else
127 @implementation NSColor(KGNoise)
128 - (NSColor *)colorWithNoiseWithOpacity:(CGFloat)opacity{
129 return [self colorWithNoiseWithOpacity:opacity andBlendMode:kCGBlendModeScreen];
130 }
131 - (NSColor *)colorWithNoiseWithOpacity:(CGFloat)opacity andBlendMode:(CGBlendMode)blendMode{
e39374c @kgn Updated CGRect declaration
authored
132 CGRect rect = {.size={kKGNoiseImageSize, kKGNoiseImageSize}};
8859b94 @kgn Adding color categories: #2
authored
133 NSImage *image = [[NSImage alloc] initWithSize:rect.size];
134 [image lockFocus];
135 CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
136 [self setFill]; CGContextFillRect(context, rect);
137 [KGNoise drawNoiseWithOpacity:opacity andBlendMode:blendMode];
138 [image unlockFocus];
139 return [NSColor colorWithPatternImage:image];
140 }
141 @end
142 #endif
143
d43aecf @kgn Added the image noise categories to the main KGNoise file so there is…
authored
144 #pragma mark - KGNoise Image
145
146 #if TARGET_OS_IPHONE
147 @implementation UIImage(KGNoise)
148 - (UIImage *)imageWithNoiseOpacity:(CGFloat)opacity{
149 return [self imageWithNoiseOpacity:opacity andBlendMode:kCGBlendModeScreen];
150 }
151 - (UIImage *)imageWithNoiseOpacity:(CGFloat)opacity andBlendMode:(CGBlendMode)blendMode{
e39374c @kgn Updated CGRect declaration
authored
152 CGRect rect = {.size=self.size};
d43aecf @kgn Added the image noise categories to the main KGNoise file so there is…
authored
153 UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0f);
154 CGContextRef context = UIGraphicsGetCurrentContext();
155 CGContextSaveGState(context);
156 [self drawAtPoint:CGPointZero];
157 CGContextScaleCTM(context, 1, -1);
158 CGContextTranslateCTM(context, 0, -CGRectGetHeight(rect));
159 CGContextClipToMask(context, rect, [self CGImage]);
160 [KGNoise drawNoiseWithOpacity:opacity andBlendMode:blendMode];
161 CGContextRestoreGState(context);
162 UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
163 UIGraphicsEndImageContext();
164 return image;
165 }
166 @end
167 #else
168 @implementation NSImage(KGNoise)
169 - (NSImage *)imageWithNoiseOpacity:(CGFloat)opacity{
170 return [self imageWithNoiseOpacity:opacity andBlendMode:kCGBlendModeScreen];
171 }
172 - (NSImage *)imageWithNoiseOpacity:(CGFloat)opacity andBlendMode:(CGBlendMode)blendMode{
e39374c @kgn Updated CGRect declaration
authored
173 CGRect rect = {.size=self.size};
d43aecf @kgn Added the image noise categories to the main KGNoise file so there is…
authored
174 NSImage *image = [[NSImage alloc] initWithSize:rect.size];
175 [image lockFocus];
176 CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
177 CGContextSaveGState(context);
178 [self drawAtPoint:CGPointZero fromRect:CGRectZero operation:NSCompositeSourceOver fraction:1];
179 CGContextClipToMask(context, rect, [self CGImageForProposedRect:NULL context:[NSGraphicsContext currentContext] hints:nil]);
180 [KGNoise drawNoiseWithOpacity:opacity andBlendMode:blendMode];
181 CGContextRestoreGState(context);
182 [image unlockFocus];
183 return image;
184 }
185 @end
186 #endif
187
6f89947 @kgn adding KGNoiseLinearGradientView and KGNoiseRadialGradientView closes #5
authored
188 #pragma mark - KGNoiseView
189
d8d6de5 @kgn initial commit of working mac example
authored
190 @implementation KGNoiseView
191
192 #if TARGET_OS_IPHONE
10e231a @kgn switching to instancetype
authored
193 - (instancetype)initWithFrame:(CGRect)frameRect{
d8d6de5 @kgn initial commit of working mac example
authored
194 #else
10e231a @kgn switching to instancetype
authored
195 - (instancetype)initWithFrame:(NSRect)frameRect{
d8d6de5 @kgn initial commit of working mac example
authored
196 #endif
197 if((self = [super initWithFrame:frameRect])){
198 [self setup];
199 }
200 return self;
201 }
202
10e231a @kgn switching to instancetype
authored
203 - (instancetype)initWithCoder:(NSCoder *)aDecoder{
d8d6de5 @kgn initial commit of working mac example
authored
204 if((self = [super initWithCoder:aDecoder])){
205 [self setup];
206 }
207 return self;
208 }
209
210 - (void)setup{
211 #if TARGET_OS_IPHONE
4e8fcac @kgn If the background color has been set, most likely from a nib, don’t o…
authored
212 if(!self.backgroundColor){
213 self.backgroundColor = [UIColor grayColor];
214 }
b198946 @danielamitay Set KGNoiseView's default contentMode to UIViewContentModeRedraw
danielamitay authored
215 self.contentMode = UIViewContentModeRedraw;
d8d6de5 @kgn initial commit of working mac example
authored
216 #else
4e8fcac @kgn If the background color has been set, most likely from a nib, don’t o…
authored
217 if(!self.backgroundColor){
218 self.backgroundColor = [NSColor grayColor];
219 }
d8d6de5 @kgn initial commit of working mac example
authored
220 #endif
221 self.noiseOpacity = 0.1;
222 self.noiseBlendMode = kCGBlendModeScreen;
223 }
224
225 #if TARGET_OS_IPHONE
226 #else
227 - (void)setBackgroundColor:(NSColor *)backgroundColor{
228 if(_backgroundColor != backgroundColor){
229 _backgroundColor = backgroundColor;
230 [self setNeedsDisplay:YES];
231 }
232 }
233 #endif
234
235 - (void)setNoiseOpacity:(CGFloat)noiseOpacity{
236 if(_noiseOpacity != noiseOpacity){
237 _noiseOpacity = noiseOpacity;
238 #if TARGET_OS_IPHONE
239 [self setNeedsDisplay];
240 #else
241 [self setNeedsDisplay:YES];
242 #endif
243 }
244 }
245
0a3622d @kgn setNeedsDisplay if blend mode changes
authored
246 - (void)setNoiseBlendMode:(CGBlendMode)noiseBlendMode{
247 if(_noiseBlendMode != noiseBlendMode){
248 _noiseBlendMode = noiseBlendMode;
249 #if TARGET_OS_IPHONE
250 [self setNeedsDisplay];
251 #else
252 [self setNeedsDisplay:YES];
253 #endif
254 }
255 }
256
d8d6de5 @kgn initial commit of working mac example
authored
257 #if TARGET_OS_IPHONE
258 - (void)drawRect:(CGRect)dirtyRect{
259 CGContextRef context = UIGraphicsGetCurrentContext();
260 #else
261 - (void)drawRect:(NSRect)dirtyRect{
262 CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
263 #endif
264 [self.backgroundColor setFill];
265 CGContextFillRect(context, self.bounds);
266 [KGNoise drawNoiseWithOpacity:self.noiseOpacity andBlendMode:self.noiseBlendMode];
267 }
268
269 @end
6f89947 @kgn adding KGNoiseLinearGradientView and KGNoiseRadialGradientView closes #5
authored
270
271 #pragma mark - KGNoiseLinearGradientView
272
273 @implementation KGNoiseLinearGradientView
0c3828d @CSGBuildBot1 Code to allow specification of gradient direction.
CSGBuildBot1 authored
274
275 - (void)setup{
276 [super setup];
277 self.gradientDirection = KGLinearGradientDirection270Degrees;
278 }
6f89947 @kgn adding KGNoiseLinearGradientView and KGNoiseRadialGradientView closes #5
authored
279
280 #if TARGET_OS_IPHONE
281 - (void)setAlternateBackgroundColor:(UIColor *)alternateBackgroundColor{
282 if(_alternateBackgroundColor != alternateBackgroundColor){
283 _alternateBackgroundColor = alternateBackgroundColor;
284 [self setNeedsDisplay];
285 }
286 }
287 #else
288 - (void)setAlternateBackgroundColor:(NSColor *)alternateBackgroundColor{
289 if(_alternateBackgroundColor != alternateBackgroundColor){
290 _alternateBackgroundColor = alternateBackgroundColor;
291 [self setNeedsDisplay:YES];
292 }
293 }
294 #endif
295
296 #if TARGET_OS_IPHONE
297 - (void)drawRect:(CGRect)dirtyRect{
298 CGContextRef context = UIGraphicsGetCurrentContext();
299 #else
300 - (void)drawRect:(NSRect)dirtyRect{
301 CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
302 #endif
303 // if we don't have an alternate color draw solid
304 if(self.alternateBackgroundColor == nil){
305 [super drawRect:dirtyRect];
306 return;
307 }
308
309 CGRect bounds = self.bounds;
310 CGContextSaveGState(context);
311 CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
312 CGFloat *components = gradientComponentsForColors(self.alternateBackgroundColor, self.backgroundColor);
313 CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, components, NULL, 2);
314 CGColorSpaceRelease(baseSpace), baseSpace = NULL;
0c3828d @CSGBuildBot1 Code to allow specification of gradient direction.
CSGBuildBot1 authored
315 CGPoint startPoint;
316 CGPoint endPoint;
317 switch (self.gradientDirection) {
318 case KGLinearGradientDirection0Degrees:
319 startPoint = CGPointMake(CGRectGetMinX(bounds), CGRectGetMidY(bounds));
320 endPoint = CGPointMake(CGRectGetMaxX(bounds), CGRectGetMidY(bounds));
321 break;
322 case KGLinearGradientDirection90Degrees:
323 startPoint = CGPointMake(CGRectGetMidX(bounds), CGRectGetMaxY(bounds));
324 endPoint = CGPointMake(CGRectGetMidX(bounds), CGRectGetMinY(bounds));
325 break;
326 case KGLinearGradientDirection180Degrees:
327 startPoint = CGPointMake(CGRectGetMaxX(bounds), CGRectGetMidY(bounds));
328 endPoint = CGPointMake(CGRectGetMinX(bounds), CGRectGetMidY(bounds));
329 break;
330 case KGLinearGradientDirection270Degrees:
331 default:
332 startPoint = CGPointMake(CGRectGetMidX(bounds), CGRectGetMinY(bounds));
333 endPoint = CGPointMake(CGRectGetMidX(bounds), CGRectGetMaxY(bounds));
334 break;
335 }
6f89947 @kgn adding KGNoiseLinearGradientView and KGNoiseRadialGradientView closes #5
authored
336 CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
337 CGGradientRelease(gradient), gradient = NULL;
338 CGContextRestoreGState(context);
339 free(components);
340
341 [KGNoise drawNoiseWithOpacity:self.noiseOpacity andBlendMode:self.noiseBlendMode];
342 }
343
344 @end
345
346 #pragma mark - KGNoiseRadialGradientView
347
348 @implementation KGNoiseRadialGradientView
349
350 #if TARGET_OS_IPHONE
351 - (void)setAlternateBackgroundColor:(UIColor *)alternateBackgroundColor{
352 if(_alternateBackgroundColor != alternateBackgroundColor){
353 _alternateBackgroundColor = alternateBackgroundColor;
354 [self setNeedsDisplay];
355 }
356 }
357 #else
358 - (void)setAlternateBackgroundColor:(NSColor *)alternateBackgroundColor{
359 if(_alternateBackgroundColor != alternateBackgroundColor){
360 _alternateBackgroundColor = alternateBackgroundColor;
361 [self setNeedsDisplay:YES];
362 }
363 }
364 #endif
365
366 #if TARGET_OS_IPHONE
367 - (void)drawRect:(CGRect)dirtyRect{
368 CGContextRef context = UIGraphicsGetCurrentContext();
369 #else
370 - (void)drawRect:(NSRect)dirtyRect{
371 CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
372 #endif
373 // if we don't have an alternate color draw solid
374 if(self.alternateBackgroundColor == nil){
375 [super drawRect:dirtyRect];
376 return;
377 }
378
379 CGRect bounds = self.bounds;
380 CGContextSaveGState(context);
381 size_t gradLocationsNum = 2;
382 CGFloat gradLocations[2] = {0.0f, 1.0f};
383 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
384 CGFloat *components = gradientComponentsForColors(self.alternateBackgroundColor, self.backgroundColor);
385 CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, gradLocations, gradLocationsNum);
386 CGColorSpaceRelease(colorSpace), colorSpace = NULL;
387 CGPoint gradCenter= CGPointMake(round(CGRectGetMidX(bounds)), round(CGRectGetMidY(bounds)));
963d03c @kgn improved the radial gradient radius code based on @marcosanson pull r…
authored
388 CGFloat gradRadius = sqrt(pow((CGRectGetHeight(bounds)/2), 2) + pow((CGRectGetWidth(bounds)/2), 2));
6f89947 @kgn adding KGNoiseLinearGradientView and KGNoiseRadialGradientView closes #5
authored
389 CGContextDrawRadialGradient(context, gradient, gradCenter, 0, gradCenter, gradRadius, kCGGradientDrawsAfterEndLocation);
390 CGGradientRelease(gradient), gradient = NULL;
391 CGContextRestoreGState(context);
392 free(components);
393
394 [KGNoise drawNoiseWithOpacity:self.noiseOpacity andBlendMode:self.noiseBlendMode];
395 }
396 @end
Something went wrong with that request. Please try again.