Из массива char * в двумерный массив и обратно алгоритм работает неправильно - PullRequest
1 голос
/ 12 сентября 2011

Я думаю, что мой алгоритм где-то имеет ошибочную логику.Вызов двух функций должен вернуть одно и то же изображение, но это не так!Кто-нибудь может увидеть, где моя логика идет не так?

Эти функции используются на PNG-изображениях, я обнаружил, что они хранят цвета следующим образом: АЛЬФА, КРАСНЫЙ, ЗЕЛЕНЫЙ, СИНИЙ.Повторно для всего изображения.«пиксели» - это просто длинный массив этих значений (например, список).

Мое намерение состоит в том, чтобы сделать фильтр нижних частот на изображении, что будет намного проще, если вы вместо этого используете двумерный массив /матрица изображения.

// loading pixels
UIImage *image      = imageView.image;
CGImageRef imageRef = image.CGImage;
NSData *data        = (NSData *)CGDataProviderCopyData(CGImageGetDataProvider(imageRef));
char *pixels        = (char *)[data bytes];

// editing image
char** matrix = [self mallocMatrix:pixels withWidth:CGImageGetWidth(imageRef) andHeight:CGImageGetHeight(imageRef)];
char* newPixels = [self mallocMatrixToList:matrix withWidth:CGImageGetWidth(imageRef) andHeight:CGImageGetHeight(imageRef)];
pixels = newPixels;

и функции выглядят следующим образом:

- (char**)mallocMatrix:(char*)pixels withWidth:(int)width andHeight:(int)height {
    char** matrix = malloc(sizeof(char*)*height);
    int c = 0;
    for (int h=0; h < height; h++) {
        matrix[h] = malloc(sizeof(char)*width*4);
        for (int w=0; w < (width*4); w++) {
            matrix[h][w] = pixels[c];
            c++;
        }
    }
    return matrix;
}

- (char*)mallocMatrixToList:(char**)matrix withWidth:(int)width andHeight:(int)height {
    char* pixels = malloc(sizeof(char)*height*width*4);
    int c = 0;
    for (int h=0; h < height; h++) {
        for (int w=0; w < (width*4); w++) {
            pixels[c] = matrix[h][w];
            c++;
        }
    }
    return pixels;
}

Редактировать: Исправлено malloc, как указано на постерах.Алгоритм немного упрощен.

1 Ответ

1 голос
/ 12 сентября 2011

Я не проверял ваш код, но, похоже, вы выделяете неправильный размер для вашей матрицы и фильтра нижних частот, а также неправильно перемещаетесь к следующему пикселю.

- (char**) mallocMatrix:(char*)pixels withWidth:(int)width andHeight:(int)height {
    //When using Objective-C do not cast malloc (only do so with Objective-C++)
    char** matrix = malloc(sizeof(char*)*height);
    for (int h=0; h < height; h++) {
        //Each row needs to malloc the sizeof(char) not char *
        matrix[h] = malloc(sizeof(char)*width*4);
        for (int w=0; w < width; w++) {
            // Varje pixel har ARGB
            for (int i=0; i < 4; i++) {
                matrix[h][w+i] = pixels[h*w+i];
            }
        }
    }
    return matrix;
}

- (char*) mallocLowPassFilter:(char**)matrix withWidth:(int)width andHeight:(int)height 
{
    //Same as before only malloc sizeof(char)
    char* pixels = malloc(sizeof(char)*height*width*4);
    for (int h=0; h < height; h++) {
        for (int w=0; w < width; w++) {
            // Varje pixel har ARGB
            for (int i=0; i < 4; i++) {
                // TODO: Lowpass here
                pixels[h*w+i] = matrix[h][w+i];
            }
        }
    }
    return pixels;
}

Примечание. Этот код, как вы знаете, ограничен изображениями ARGB. Если вы хотите поддерживать больше форматов изображений, для получения дополнительной информации о вашем изображении доступны дополнительные функции, такие как CGImageGetColorSpace для поиска формата пикселей (ARGB, RGBA, RGB и т. Д.) И CGImageGetBytesPerRow для получения количества байтов в строке (вам не нужно умножать ширину на каналы на пиксель).

...