4

私の全体像の目標は、画像の上に灰色のフィールドを配置することです。ユーザーがその灰色のフィールドをこすると、下の画像が表示されます。基本的に宝くじのスクラッチカードのようなものです。ドキュメントやこのサイトをたくさん検索しましたが、解決策が見つかりません。

以下は、ユーザーが触れた場所に基づいて画像を「消去」することをテストするための概念実証ですが、機能していません。:(

私はタッチを検出する UIView を持っており、次のようにして UIImageView で画像をクリップする UIViewController に移動の座標を送信します。

- (void) moveDetectedFrom:(CGPoint) from to:(CGPoint) to
{
    UIImage* image = bkgdImageView.image;
    CGSize s = image.size;
    UIGraphicsBeginImageContext(s);
    CGContextRef g = UIGraphicsGetCurrentContext();

    CGContextMoveToPoint(g, from.x, from.y);
    CGContextAddLineToPoint(g, to.x, to.y);
    CGContextClosePath(g);
    CGContextAddRect(g, CGRectMake(0, 0, s.width, s.height));
    CGContextEOClip(g);
    [image drawAtPoint:CGPointZero];
    bkgdImageView.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    [bkgdImageView setNeedsDisplay];
}

問題は、タッチがこのメソッドに問題なく送信されることですが、オリジナルでは何も起こりません。

クリップパスを間違って実行していますか? または?

よくわからないので、何か助けていただければ幸いです。

前もって感謝します、ジョエル

4

2 に答える 2

1

通常、古いメソッドだけでなく、drawRect:メソッド内の現在のグラフィックスコンテキストに描画する必要があります。また、クリップ領域は、現在のグラフィックスコンテキストに描画されるものにのみ影響します。しかし、なぜこのアプローチが機能しないのかを説明する代わりに、別の方法で行うことをお勧めします。

私がすることは2つの見方をすることです。1つは画像、もう1つは透明にした灰色です。これにより、グレーの塗りつぶしを変更するたびに画像を再描画するのではなく、グラフィックハードウェアが画像をキャッシュできるようになります。

灰色のものは、CGBitmapContextを持つUIViewサブクラスであり、ユーザーがタッチするピクセルを明確にするために描画します。

これを行うには、おそらくいくつかの方法があります。上記の1つの方法を提案しているだけです。

于 2010-06-05T03:47:58.930 に答える
1

私はずっと前に Core Graphics だけを使って同じことをしようとしてきましたが、それは可能ですが、その効果はユーザーが期待するほどスムーズでもソフトでもありません。だから、OpenCV (Open Computer Vision Library) の使い方を知っていて、C で書かれているので、iPhone で使えることを知っていました。OpenCV でやりたいことを行うのは非常に簡単です。最初に、UIImage を IplImage に変換するための関数がいくつか必要です。IplImage は、あらゆる種類の画像を表すために OpenCV で使用されるタイプです。

+ (IplImage *)CreateIplImageFromUIImage:(UIImage *)image {
CGImageRef imageRef = image.CGImage;
//This is the function you use to convert a UIImage -> IplImage
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

IplImage *iplimage = cvCreateImage(cvSize(image.size.width, image.size.height), IPL_DEPTH_8U, 4);
CGContextRef contextRef = CGBitmapContextCreate(iplimage->imageData, iplimage->width, iplimage->height,
                                                iplimage->depth, iplimage->widthStep,
                                                colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault);
CGContextDrawImage(contextRef, CGRectMake(0, 0, image.size.width, image.size.height), imageRef);


CGContextRelease(contextRef);

CGColorSpaceRelease(colorSpace);

return iplimage;}



+ (UIImage *)UIImageFromIplImage:(IplImage *)image {

//Convert a IplImage -> UIImage
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSData * data = [[NSData alloc] initWithBytes:image->imageData length:image->imageSize];
//NSData *data = [NSData dataWithBytes:image->imageData length:image->imageSize];
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)data);
CGImageRef imageRef = CGImageCreate(image->width, image->height,
                                    image->depth, image->depth * image->nChannels, image->widthStep,
                                    colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault,
                                    provider, NULL, false, kCGRenderingIntentDefault);
UIImage *ret = [[UIImage alloc] initWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
[data release];
return ret;}

必要な基本機能が両方揃ったので、IplImage を使って好きなことを行うことができます。これが目的です。

+(UIImage *)erasePointinUIImage:(IplImage *)image :(CGPoint)point :(int)r{
//r is the radious of the erasing
    int a = point.x;
 int b = point.y;
 int position;
 int minX,minY,maxX,maxY;
 minX = (a-r>0)?a-r:0;
 minY = (b-r>0)?b-r:0;
 maxX = ((a+r) < (image->width))? a+r : (image->width);
 maxY = ((b+r) < (image->height))? b+r : (image->height);

 for (int i = minX; i < maxX ; i++)
 {
    for(int j=minY; j<maxY;j++)
    {
        position =  ((j-b)*(j-b))+((i-a)*(i-a));
        if (position <= r*r)
        {
            uchar* ptr =(uchar*)(image->imageData) + (j*image->widthStep + i*image->nChannels);
            ptr[1] = ptr[2] = ptr[3] = ptr[4] = 0;
        }
    }
}
UIImage * res = [self UIImageFromIplImage:image]; 
return res;}

整形でごめんなさい。

OpenCVをiPhoneに移植する方法を知りたい方は丹羽義正さんの

現在 OpenCV で動作しているアプリを AppStore で確認したい場合は、Flags&Faces を入手してください。

于 2010-07-09T14:53:06.707 に答える