10

我的项目中有一个奇怪的问题。我想要做的是,用户将使用在图像上滑动作为覆盖来绘制或绘制,我只需要从绘制区域下方的图像中裁剪区域。UIImage只有当绘制区域下方的视图为 320 像素宽(即 iPhone 的宽度)时,我的代码才能正常工作。但是如果我改变 的宽度ImageView,我不会得到想要的结果。

我正在使用以下代码CGRect在绘制的部分周围构建一个。

-(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 像素宽并跨越整个屏幕宽度时,此代码运行良好。但是如果图像视图的宽度小于 300 并且放置在屏幕的中心,则代码会给出错误的结果。

注意:我正在根据 imageview 的宽度缩放图像。

下面是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 图像运行良好,不受 imageview 宽度变化的影响。但即使我正在处理方向,JPEG 仍然无法正常工作。

4

1 回答 1

2

First, I wonder if you're accessing something other than 32-bit RGBA? The index value for data[] is stored in pixelInfo then moves +2 bytes, rather than +3. That would land you on the blue byte. If your intent is to use RGBA, that fact would affect the rest of the results of your code.

Moving on, with an assumption that you were still getting flawed results despite having the correct alpha component value, it seems your "fixed" code would give Left,Right,Top,Bottom NSLog outputs with alpha values less than the full-on 255, something close to 0. In this case, without further code, I'd suggest your problem is within the code you use to scale down the image from your 320x240 source to 300x225 (or perhaps any other scaled dimensions). I could imagine your image having alpha values at the edge of 255 if your "scale" code is performing a crop rather than a scale.

于 2013-05-27T03:50:28.180 回答