2012-01-05 2 views
3

Я использую эту функцию, чтобы определить, соответствует ли затронутая точка UIImageView прозрачному пикселю или нет.Обнаружение альфа-канала на преобразованном изображении в UIImageView

-(BOOL)isTransparency:(CGPoint)point 
{ 
    CGImageRef cgim = self.image.CGImage; 

    unsigned char pixel[1] = {0}; 

    point.x = (point.x/(self.frame.size.width/CGImageGetWidth(cgim))); 
    point.y = (point.y/(self.frame.size.height/CGImageGetHeight(cgim))); 


    CGContextRef context = CGBitmapContextCreate(pixel, 
               1, 1, 8, 1, NULL, 
               kCGImageAlphaOnly); 

    CGContextSetBlendMode(context, kCGBlendModeCopy); 

    CGContextDrawImage(context, CGRectMake(-point.x, 
              -(self.image.size.height - point.y), 
              CGImageGetWidth(cgim), 
              CGImageGetHeight(cgim)), 
         cgim); 

    CGContextRelease(context); 

    CGFloat alpha = pixel[0]/255.0; 

    return alpha < 0.01; 

} 

Отлично работает, если преобразование UIImageView не изменяется. Но когда пользователь поворачивает изображение, матрица преобразования модифицируется, этот код получает изображение в исходном положении, не соответствующее преобразованной позиции изображения, и я получаю ложные результаты.

Мой вопрос: как я могу определить, прозрачен ли прикосненный пиксель изображения UIImageView при его повороте?

Спасибо.

EDIT: -Version 1.1-

Привет. Спасибо за ответ. Я изменил код, и теперь эта версия до сих пор работает в предыдущей версии:

-(BOOL)isTransparency:(CGPoint)point 
{ 
    CGImageRef cgim = self.image.CGImage; 

    NSLog(@"Image Size W:%lu H:%lu",CGImageGetWidth(cgim),CGImageGetHeight(cgim)); 

    unsigned char pixel[1] = {0}; 

    point.x = (point.x/(self.frame.size.width/CGImageGetWidth(cgim))); 
    point.y = (point.y/(self.frame.size.height/CGImageGetHeight(cgim))); 


    CGContextRef context = CGBitmapContextCreate(pixel, 
               1, 1, 8, 1, NULL, 
               kCGImageAlphaOnly); 

    CGContextSetBlendMode(context, kCGBlendModeCopy); 

    CGContextTranslateCTM(context, self.image.size.width * 0.5f, self.image.size.height * 0.5f); 
    CGContextConcatCTM(context, self.transform); 
    //CGContextScaleCTM(context, [self currentPercent]/100, [self currentPercent]/100); 
    //CGContextRotateCTM(context, atan2f(self.transform.b, self.transform.a)); 
    CGContextTranslateCTM(context, -self.image.size.width * 0.5f, -self.image.size.height * 0.5f); 

    CGContextDrawImage(context, CGRectMake(-point.x, 
              -(self.image.size.height - point.y), 
              self.image.size.width, 
              self.image.size.height), 
         cgim); 

    CGContextRelease(context); 

    CGFloat alpha = pixel[0]/255.0; 

    NSLog(@"Is Transparent: %d",alpha < 0.01); 

    return alpha < 0.01; 

} 

Я попытался с несколькими функциями, чтобы вращать и масштабировать исходное изображение текущего вращения и размер без успеха. :(

Любая помощь, пожалуйста,

EDIT:. Version 1.2

Я нашел обходной путь, чтобы решить эту проблему, я решил создать контекст с размером, равным размеру экрана и рисовать только прикоснулся объект, в соответствии с текущим преобразованием матрицы.

После этого я создаю изображение для этого контекста, в котором изображение правильно нарисованной и передать изображение на функцию, которая работает только с не трансформированных изображений.

В результате работает нормально. Я не знаю, является ли это оптимальным способом, но работает.

Вот код:

-(BOOL)isTransparency:(CGPoint)point 
{ 
    UIGraphicsBeginImageContext(self.superview.bounds.size); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    CGContextSaveGState(context); 

    CGContextSetBlendMode(context, kCGBlendModeCopy); 

    CGContextTranslateCTM(context, [self center].x, [self center].y); 
    CGContextConcatCTM(context, [self transform]); 
    CGContextTranslateCTM(context, 
          -[self bounds].size.width * [[self layer] anchorPoint].x, 
          -[self bounds].size.height * [[self layer] anchorPoint].y); 

    [[self image] drawInRect:[self bounds]]; 

    CGContextRestoreGState(context); 

    CGImageRef image = CGBitmapContextCreateImage(context); 

    CGImageRef viewImage = image; 

    return [self isTransparentPixel:point image:image]; 

} 

Эта функция создает изображение с размером надтаблицы (в моем случае всегда полный экран) и принимает в качестве параметра прикоснулся точки в системе координат UIKit от родительского вида.

-(BOOL)isTransparentPixel:(CGPoint)point image:(CGImageRef)cgim 
{ 
    NSLog(@"Image Size W:%lu H:%lu",CGImageGetWidth(cgim),CGImageGetHeight(cgim)); 

    unsigned char pixel[1] = {0}; 

    CGContextRef context = CGBitmapContextCreate(pixel, 
               1, 1, 8, 1, NULL, 
               kCGImageAlphaOnly); 

    CGContextSetBlendMode(context, kCGBlendModeCopy); 

    CGContextDrawImage(context, CGRectMake(-point.x, 
              -(self.superview.frame.size.height - point.y), 
              CGImageGetWidth(cgim), 
              CGImageGetHeight(cgim)), 
         cgim); 

    CGContextRelease(context); 

    CGFloat alpha = pixel[0]/255.0; 

    return alpha < 0.01; 

} 

Эта функция определяет альфа-канал заданного пикселя в заданном изображении.

Спасибо за все.

ответ

2

Примените преобразование из вашего изображения к вашему CGContext с помощью функции, такой как CGContextConcatCTM(), прежде чем рисовать изображение.

+0

Я пробовал, но не работает. В вопросе я редактировал версию функции с помощью функции Concat, Rotate и Scale, но безуспешно. – NemeSys

+0

Возможно, вам придется перейти в центр размера изображения, если он отличается от изображения. На данный момент проще было бы сделать контекст полным размером изображения и записать этот CGImage на диск или отобразить его в новом представлении, чтобы убедиться, что преобразования применяются правильно. –

Смежные вопросы