我试图通过读取像素值从水平条中选择带有imageViews的颜色,这是一种水平颜色选择器
但由于层次结构,我无法检索正确的颜色,因为发送旋钮的点有一些问题 - 查看 - UIImageview(红色) - UIImageview(绿色) - UIimageview(蓝色) - 等......
以下是代码
故事板:我试图通过读取像素值从水平条中选择带有imageViews的颜色,这是一种水平颜色选择器
但由于层次结构,我无法检索正确的颜色,因为发送旋钮的点有一些问题 - 查看 - UIImageview(红色) - UIImageview(绿色) - UIimageview(蓝色) - 等......
以下是代码
故事板:
#import "EffViewController.h"
#import "TouchMoveGestureRecognizer.h"
@interface EffViewController ()
@end
@implementation EffViewController
@synthesize colorPicker,sliders,sliderValues,picker;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
for (ColorPickerImageView *colorPickers in _colorPickerArray) {
colorPickers.pickedColorDelegate = self;
}
//colorPicker.pickedColorDelegate = self;
TouchMoveGestureRecognizer* gr = [[TouchMoveGestureRecognizer alloc] init];
[picker addGestureRecognizer: gr];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getTheColorPickerData:) name:@"getTheColorPickerData" object:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) pickedColor:(UIColor*)color atPoint:(CGPoint)point{
[picker setHidden:false];
self.view.backgroundColor = color;
// Convert point Positions from colorpickerview to main view
CGPoint pointInViewCoords = [self.view convertPoint:point fromView:colorPicker];
//[picker setCenter:pointInViewCoords];
CGColorRef cgcolor = [color CGColor];
int numComponents = CGColorGetNumberOfComponents(cgcolor);
if (numComponents == 4){
const CGFloat *components = CGColorGetComponents(cgcolor);
for(UISlider *slider in sliders)
[slider setValue: components[[slider tag]-1]*255.0f];
for(UITextField *text in sliderValues){
int intValue = components[[text tag]-1]*255;
[text setText:[NSString stringWithFormat:@"%d",intValue]];
}
}
}
- (void)getTheColorPickerData:(NSNotification*)notification
{
// 1
//UIEvent *event = notification.userInfo[@"events"];
NSSet *touches = notification.userInfo[@"touches"];
UITouch* t = [touches anyObject];
CGPoint Worldpoint = [t locationInView: self.colorPickerViewFrame];
//point.y = picker.frame.origin.y;
NSLog(@"World Points x:%f y:%f",Worldpoint.x,Worldpoint.y);
[picker setHidden:false];
CGPoint point = picker.frame.origin;//[[[event allTouches] anyObject] locationInView:self.view];
point.y = picker.frame.size.height/2;
UIControl *control = picker;
NSLog(@"Points x:%f y:%f",point.x,point.y);
NSLog(@"Color Picker Points x :%f y:%f w:%f h:%f",[colorPicker frame].origin.x,[colorPicker frame].origin.y,[colorPicker frame].size.width,[colorPicker frame].size.height);
for (ColorPickerImageView *colorPickers in _colorPickerArray) {
if (CGRectContainsPoint([colorPickers frame], point)) {
// control.center = point;
//[colorPicker touchesEnded:[event allTouches] withEvent:event];
[colorPicker imageSelectionEnded:point];
}
}
}
TouchMoveGesture
#import "TouchMoveGestureRecognizer.h"
@implementation TouchMoveGestureRecognizer
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch* t = [touches anyObject];
_ptOffset = [t locationInView: self.view];
// if(![self isInsideTheBoundary:_ptOffset]){
// return;
// }
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch* t = [touches anyObject];
CGPoint pt = [t locationInView: self.view.superview];
float ptYtemp;
// if(![self isInsideTheBoundary:pt]){
// return;
// }
if ((pt.x < 295.0f && pt.x > 25.0f) == NO) {
return;
}
pt.x -= _ptOffset.x;
ptYtemp = pt.y;
pt.y -= _ptOffset.y;
if ((pt.y < 26.0f && pt.y > 24.0f) == NO) {
pt.y=ptYtemp;
}
CGRect r = self.view.frame;
r.origin.x = pt.x;
self.view.frame = r;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
_ptOffset = CGPointMake(0, 0);
[[NSNotificationCenter defaultCenter] postNotificationName:@"getTheColorPickerData"
object:self
userInfo:@{@"touches":touches,
@"events":event}];
}
-(BOOL) isInsideTheBoundary :(CGPoint) location {
BOOL isInsideBoundary = NO;
// NSLog(@"Location x:%f y:%f",location.x,location.y);
if (location.x < 320.0f && location.x > 0.0f) {
if (location.y < 31.0f && location.y > 26.0f) {
return YES;
}
}
return NO;
}
@end
ColorPickerImageView
#import "ColorPickerImageView.h"
#import "EffViewController.h"
#import <CoreGraphics/CoreGraphics.h>
#import <QuartzCore/CoreAnimation.h>
@implementation ColorPickerImageView
@synthesize lastColor;
@synthesize pickedColorDelegate;
- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
if (self.hidden==YES) {
//color wheel is hidden, so don't handle this as a color wheel event.
[[self nextResponder] touchesEnded:touches withEvent:event];
return;
}
UITouch* touch = [touches anyObject];
CGPoint point = [touch locationInView:self]; //where image was tapped
}
-(void)imageSelectionEnded:(CGPoint)point {
if (self.hidden==YES) {
//color wheel is hidden, so don't handle this as a color wheel event.
// [[self nextResponder] touchesEnded:touches withEvent:event];
return;
}
self.lastColor = [self getPixelColorAtLocation:point];
NSLog(@"color %@",lastColor);
[pickedColorDelegate pickedColor:(UIColor*)self.lastColor atPoint:point];
}
- (UIColor*) getPixelColorAtLocation:(CGPoint)point {
UIColor* color = nil;
CGImageRef inImage = self.image.CGImage;
// Create off screen bitmap context to draw the image into. Format ARGB is 4 bytes for each pixel: Alpa, Red, Green, Blue
CGContextRef cgctx = [self createARGBBitmapContextFromImage:inImage];
if (cgctx == NULL) { return nil; /* error */ }
size_t w = CGImageGetWidth(inImage);
size_t h = CGImageGetHeight(inImage);
CGRect rect = {{0,0},{w,h}};
/** Extra Added code for Resized Images ****/
float xscale = w / self.frame.size.width;
float yscale = h / self.frame.size.height;
point.x = point.x * xscale;
point.y = point.y * yscale;
/** ****************************************/
/** Extra Code Added for Resolution ***********/
CGFloat x = 1.0;
if ([self.image respondsToSelector:@selector(scale)]) x = self.image.scale;
/*********************************************/
// Draw the image to the bitmap context. Once we draw, the memory
// allocated for the context for rendering will then contain the
// raw image data in the specified color space.
CGContextDrawImage(cgctx, rect, inImage);
// Now we can get a pointer to the image data associated with the bitmap
// context.
unsigned char* data = CGBitmapContextGetData (cgctx);
if (data != NULL) {
//offset locates the pixel in the data from x,y.
//4 for 4 bytes of data per pixel, w is width of one row of data.
// int offset = 4*((w*round(point.y))+round(point.x));
int offset = 4*((w*round(point.y))+round(point.x))*x; //Replacement for Resolution
int alpha = data[offset];
int red = data[offset+1];
int green = data[offset+2];
int blue = data[offset+3];
NSLog(@"offset: %i colors: RGB A %i %i %i %i",offset,red,green,blue,alpha);
color = [UIColor colorWithRed:(red/255.0f) green:(green/255.0f) blue:(blue/255.0f) alpha:(alpha/255.0f)];
}
// When finished, release the context
CGContextRelease(cgctx);
// Free image data memory for the context
if (data) { free(data); }
return color;
}
- (CGContextRef) createARGBBitmapContextFromImage:(CGImageRef) inImage {
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
void * bitmapData;
int bitmapByteCount;
int bitmapBytesPerRow;
// Get image width, height. We'll use the entire image.
size_t pixelsWide = CGImageGetWidth(inImage);
size_t pixelsHigh = CGImageGetHeight(inImage);
// Declare the number of bytes per row. Each pixel in the bitmap in this
// example is represented by 4 bytes; 8 bits each of red, green, blue, and
// alpha.
bitmapBytesPerRow = (pixelsWide * 4);
bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
// Use the generic RGB color space.
colorSpace = CGColorSpaceCreateDeviceRGB();
if (colorSpace == NULL)
{
fprintf(stderr, "Error allocating color space\n");
return NULL;
}
// Allocate memory for image data. This is the destination in memory
// where any drawing to the bitmap context will be rendered.
bitmapData = malloc( bitmapByteCount );
if (bitmapData == NULL)
{
fprintf (stderr, "Memory not allocated!");
CGColorSpaceRelease( colorSpace );
return NULL;
}
// Create the bitmap context. We want pre-multiplied ARGB, 8-bits
// per component. Regardless of what the source image format is
// (CMYK, Grayscale, and so on) it will be converted over to the format
// specified here by CGBitmapContextCreate.
context = CGBitmapContextCreate (bitmapData,
pixelsWide,
pixelsHigh,
8, // bits per component
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedFirst);
if (context == NULL)
{
free (bitmapData);
fprintf (stderr, "Context not created!");
}
// Make sure and release colorspace before returning
CGColorSpaceRelease( colorSpace );
return context;
}
@end