vendredi 8 mai 2015

iOS using UIGraphicsGetImageFromCurrentImageContext to detect certain pixels on screen

I have a UIView where the user can draw various UIBezierPaths.

I need to analyze the drawn BezierPaths to process certain patterns. I have not found any solution to converting UIBezierPaths to a list of coordinates/points, it seems like this is undoable? It's strange as this data must be stored and used someway to draw the actual paths..

So to bypass this problem i decided to draw the BezierPath with a width of 1px:

[path setLineWidth:1];

And convert my UIView to an UIImage:

UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();

Then i can identify pixels by getting the color for a certain pixel position at the image:

- (UIColor *)colorAtPixel:(CGPoint)point {
    CGImageRef imageRef = [self CGImage];
    NSUInteger width = CGImageGetWidth(imageRef);
    NSUInteger height = CGImageGetHeight(imageRef);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    int bytesPerPixel = 4;
    long bytesPerRow = bytesPerPixel * width;
    int bitsPerComponent = 8;

    unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));

    CGContextRef context = CGBitmapContextCreate(rawData,
                                                 width,
                                                 height,
                                                 bitsPerComponent,
                                                 bytesPerRow,
                                                 colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

    CGColorSpaceRelease(colorSpace);
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    CGContextRelease(context);

    // Now your rawData contains the image data in the RGBA8888 pixel format.
    long byteIndex = (bytesPerRow * point.y) + point.x * bytesPerPixel;
    CGFloat red   = (rawData[byteIndex] * 1.0) / 255.0;
    CGFloat green = (rawData[byteIndex + 1] * 1.0) / 255.0 ;
    CGFloat blue  = (rawData[byteIndex + 2] * 1.0) / 255.0 ;
    CGFloat alpha = (rawData[byteIndex + 3] * 1.0) / 255.0;

    byteIndex += 4;
    UIColor *color = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
    free(rawData);

    return color;
}

Now my issue is that the image generated is blurry, if a draw a straight 1px BezierPath line and convert this to an UIImage, the line has a width of 3x because of it becomming blurry.

How can i solve this? Is there actually no possible way to convert BezierPaths to a list of coordinates?

Aucun commentaire:

Enregistrer un commentaire