Введенная область в UIImage не распознана правильно

У меня возникла странная проблема в моем проекте. Я хочу, чтобы пользователь рисовал или рисовал, используя салфетки над изображением в качестве наложения, и мне просто нужно обрезать область из изображения, расположенного ниже окрашенной области. Мой код работает хорошо, только если представление 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 - крайние значения (от CGPoint) в float, которые вычисляются, когда пользователь проводит пальцем по экрану во время покраски и представляет прямоугольник, который содержит окрашенную область в ее (чтобы минимизировать цикл).

    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 и помещается в центр экрана, код дает ложный результат.

Примечание. Я масштабирую изображение в соответствии с шириной изображения.

Ниже вывод NSLog:

  • Если ширина изображения составляет 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
    
  • Когда ширина изображения составляет 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
    

Как я могу решить эту проблему, потому что мне нужно изображение в центре с отступом на обе стороны.

EDIT: Ок, похоже, моя проблема связана с ориентацией изображений изображений JPEG (с камеры). Изображения Png работают хорошо и не меняются при изменении ширины изображения. Но все же JPEG не работают, даже если я занимаюсь ориентацией.

Ответ 1

Во-первых, мне интересно, получаете ли вы что-то, кроме 32-битного RGBA? Значение индекса для данных [] сохраняется в pixelInfo, а затем перемещает +2 байта, а не +3. Это вывело бы вас на синий байт. Если вы намерены использовать RGBA, этот факт повлияет на остальные результаты вашего кода.

Двигаясь дальше, полагая, что вы все еще получаете недостатки, несмотря на то, что у вас есть правильное значение альфа-компонента, кажется, что ваш "фиксированный" код будет давать выходы Left, Right, Top, Bottom NSLog с альфа-значениями, на 255, что-то близкое к 0. В этом случае без дополнительного кода я бы предположил, что ваша проблема находится в коде, который вы используете для масштабирования изображения с вашего источника 320x240 до 300x225 (или, возможно, любых других масштабированных измерений). Я мог представить ваше изображение с альфа-значениями на границе 255, если ваш "масштабный" код выполняет урожай, а не масштаб.