2012-01-05 5 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:バージョン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

画像を描画する前に、CGContextConcatCTM()などの関数を使用して、画像ビューからCGContextに変換を適用します。

+0

私は試みましたが、機能していませんでした。私は、Concat、Rotate、Scale機能を持つ関数のバージョンを編集しましたが、成功しませんでした。 – NemeSys

+0

画像ビューと同じサイズでない場合は、画像ビューのサイズの中央に移動する必要があります。現在のところ、イメージビューのフルサイズをコンテキストに描画し、そのCGImageをディスクに書き込むか、新しいビューに表示する方が、変換が正しく適用されるようにする方が簡単かもしれません。 –

関連する問題