2

iPadにpng画像、寸法1214x1214(網膜の場合は2倍)があり、画面座標(0、-20)にあるUIImageViewとして設定しています。デバイスの回転/向きの変更中に画面にフィットするように、アスペクト フィット タイプに設定しました。

私がやりたいことは、画面に触れて、タッチの下にあるピクセルの RGB 値を読み取れるようにすることです。UIGestureRecognizer を実装し、それを UIImage に関連付けて、タッチ座標を正常に取得しています。

問題を引き起こしているのは、RGB値を取得するいくつかの方法を実装しようとしたことです(たとえば、[iPhoneの画像のピクセルのRGB値を取得する方法])1 しかし、私のRGB値は画像のように見えますUIView の別の場所に歪んでマッピングされます。

私の質問は、UIImageView を Aspect Fit に設定したという事実と、デバイスが横向きまたは縦向き (逆さままたは右向き) である可能性があるという事実にどのように対応できるかということです。

4

1 に答える 1

1

これは、似たようなことをしようとしている人にとって役立つかもしれません。

別の回答からこの関数を使用して、画像のスケーリングされたサイズを計算しました

-(CGRect)frameForImage:(UIImage*)image inImageViewAspectFit:(UIImageView*)imageView
{
    float imageRatio = image.size.width / image.size.height;

    float viewRatio = imageView.frame.size.width / imageView.frame.size.height;

    if(imageRatio < viewRatio)
    {
        float scale = imageView.frame.size.height / image.size.height;

        float width = scale * image.size.width;

        float topLeftX = (imageView.frame.size.width - width) * 0.5;

        return CGRectMake(topLeftX, 0, width, imageView.frame.size.height);
    }
    else
    {
        float scale = imageView.frame.size.width / image.size.width;

        float height = scale * image.size.height;

        float topLeftY = (imageView.frame.size.height - height) * 0.5;

        return CGRectMake(0, topLeftY, imageView.frame.size.width, height);
    }
}

関数をリスナーとして登録することからタッチポイントを取得しました

CGPoint tapPoint = [sender locationInView:imageMap];

iPadの回転によって画像が移動した場所に基づいてタッチポイントを変更しました

if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait ||
   [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown )
  {
  // portrait (y has increased, x has stayed the same)
  tapPoint.y -= rectScaleSize.origin.y;
  }
else  
  {
  // landscape (x has increased, y has stayed the same)
  tapPoint.x -= rectScaleSize.origin.x;
  }

次に、画像の元のサイズとその Aspect Fit サイズに基づいて再スケーリングされます

tapPoint.x = (tapPoint.x * imageMap.image.size.width) / rectScaleSize.size.width;
tapPoint.y = (tapPoint.y * imageMap.image.size.height) / rectScaleSize.size.height;

ここで、imageMap.image は元の画像であり、rectScaleSize は frameForImage 関数からの戻り値でした

そして、最終的にRGB値を取得しました

CGImageRef image  = [imageMap.image CGImage];
NSUInteger width  = CGImageGetWidth(image);
NSUInteger height = CGImageGetHeight(image);
// NSLog(@"RGB Image is %d x %d",width,height);

CGColorSpaceRef colorSpace  = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData      = malloc(height * width * 4);
NSUInteger bytesPerPixel    = 4;
NSUInteger bytesPerRow      = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;

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

CGContextDrawImage(context, CGRectMake(0, 0, width, height),image);
CGContextRelease(context);

int byteIndex = (bytesPerRow * (int)tapPoint.y) + (int)tapPoint.x * bytesPerPixel;
int red = rawData[byteIndex];
int green = rawData[byteIndex + 1];
int blue = rawData[byteIndex + 2];
//int alpha = rawData[byteIndex + 3];

NSLog(@"RGB is %d,%d,%d",red,green,blue);

うまく機能しているようです。役に立つことを願っています。私がひどく間違ったことをした場合は、コメントを歓迎します!

于 2012-06-13T19:49:47.143 に答える