10

プロジェクトで奇妙な問題が発生しています。私がやりたいことは、ユーザーがオーバーレイとして画像をスワイプしてペイントまたは描画し、ペイントされた領域の下にある画像から領域をトリミングするだけでよいということです。UIImage私のコードは、ペイント領域の下にあるビューの幅が 320 ピクセル、つまり iPhone の幅の場合にのみうまく機能します。しかし、幅を変更するとImageView、目的の結果が得られません。

次のコードを使用してCGRect、塗装部分の周りに a を作成しています。

-(CGRect)detectRectForFaceInImage:(UIImage *)image{
    int l,r,t,b;
    l = r = t = b = 0;

    CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage));
    const UInt8* data = CFDataGetBytePtr(pixelData);

    BOOL pixelFound = NO;

    for (int i = leftX ; i < rightX; i++) {
        for (int j = topY; j < bottomY + 20; j++) {
            int pixelInfo = ((image.size.width  * j) + i ) * 4;
            UInt8 alpha = data[pixelInfo + 2];
            if (alpha) {
                NSLog(@"Left %d", alpha);
                l = i;
                pixelFound = YES;
                break;
            }
        }
        if(pixelFound) break;
    }

    pixelFound = NO;
    for (int i =  rightX ; i >= l; i--) {
        for (int j = topY; j < bottomY ; j++) {
            int pixelInfo = ((image.size.width  * j) + i ) * 4;
            UInt8 alpha = data[pixelInfo + 2];
            if (alpha) {
                NSLog(@"Right %d", alpha);
                r = i;
                pixelFound = YES;
                break;
            }
        }
        if(pixelFound) break;
    }

    pixelFound = NO;
    for (int i = topY ; i < bottomY ; i++) {
        for (int j = l; j < r; j++) {
            int pixelInfo = ((image.size.width  * i) + j ) * 4;
            UInt8 alpha = data[pixelInfo + 2];
            if (alpha) {
                NSLog(@"Top %d", alpha);
                t = i;
                pixelFound = YES;
                break;
            }
        }
        if(pixelFound) break;
    }

    pixelFound = NO;
    for (int i = bottomY ; i >= t; i--) {
        for (int j = l; j < r; j++) {
            int pixelInfo = ((image.size.width  * i) + j ) * 4;
            UInt8 alpha = data[pixelInfo + 2];
            if (alpha) {
                NSLog(@"Bottom %d", alpha);
                b = i;
                pixelFound = YES;
                break;
            }
        }
        if(pixelFound) break;
    }

    CFRelease(pixelData);


    return CGRectMake(l, t, r - l, b-t);
}

上記のコードでは、leftX、rightX、topY、bottomY は、ユーザーがペイント中に画面上で指をスワイプしたときに計算される float の極値 (からCGPoint) であり、境界内にペイントされた領域を含む四角形を表します (ループを最小化するため) )。

    leftX   -  minimum in X-axis
    rightX  -  maximum in X-axis
    topY    -  min in Y-axis
    bottom  -  max in Y-axis 

ここで、l、r、t、b は実際の長方形の計算値です。

前述のように、このコードは、ペインティングが行われるイメージ ビューの幅が 320 ピクセルで、画面幅全体に広がっている場合にうまく機能します。しかし、imageview の幅が 300 のように小さく、画面の中央に配置されている場合、コードは誤った結果を返します。

注:イメージビューの幅に応じて画像をスケーリングしています。

以下はNSLog出力です。

  1. imageview の幅が 320 ピクセルの場合 (これらは、一致したピクセルまたは非透過ピクセルでの色のコンポーネントの値です):

    2013-05-17 17:58:17.170 FunFace[12103:907] Left 41
    2013-05-17 17:58:17.172 FunFace[12103:907] Right 1
    2013-05-17 17:58:17.173 FunFace[12103:907] Top 73
    2013-05-17 17:58:17.174 FunFace[12103:907] Bottom 12
    
  2. imageview の幅が 300 ピクセルの場合:

    2013-05-17 17:55:26.066 FunFace[12086:907] Left 42
    2013-05-17 17:55:26.067 FunFace[12086:907] Right 255
    2013-05-17 17:55:26.069 FunFace[12086:907] Top 42
    2013-05-17 17:55:26.071 FunFace[12086:907] Bottom 255
    

両側にパディングのあるイメージビューが中央に必要なため、この問題を解決するにはどうすればよいですか。

編集:私の問題は、JPEG画像(カメラから)の画像の向きが原因のようです。PNG 画像は正常に機能しており、画像ビューの幅を変更しても影響を受けません。しかし、向きを処理していてもJPEGは機能しません。

4

1 に答える 1

2

まず、32 ビット RGBA 以外のものにアクセスしているのだろうか? data[] のインデックス値は pixelInfo に格納され、+3 ではなく +2 バイト移動します。それはあなたを青いバイトに着陸させます。あなたの意図が RGBA を使用することである場合、その事実はコードの残りの結果に影響を与えます。

次に進むと、正しいアルファ コンポーネント値を持っているにもかかわらず、まだ欠陥のある結果が得られているという前提で、「修正された」コードは、フルオンの 255 よりも小さいアルファ値を持つ左、右、上、下の NSLog 出力を与えるようです。この場合、追加のコードがなければ、問題は 320x240 ソースから 300x225 (または他のスケーリングされた寸法) に画像を縮小するために使用するコード内にあることをお勧めします。「スケール」コードがスケールではなくトリミングを実行している場合、画像のアルファ値が 255 の端にあると想像できます。

于 2013-05-27T03:50:28.180 に答える