Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Развернуть 8-битный bmp на 90 градусов 
:(
    Опции темы
kurtis
Дата 25.9.2011, 22:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 10.8.2007

Репутация: нет
Всего: нет



Пытаюсь развернуть картинку на 90 градусов, в итоге, вместо картинки, получаю непонятный мусор. Исходное изображение 8-ми битное, разрешение 600 на 800 пикселей.
Вот моя функция разворота (пожалуйста, не обращайте внимание на оптимальность алгоритма, код сырой)
Код

static int rotate_image()
{
    int x_size = info.width; //600
    int y_size = info.height; //800
    int x, y;
    unsigned char dest_img[y_size][x_size];//rotated image
    unsigned char src_img[x_size][y_size];//source image

    memcpy(src_img, image, img_sz);

    for (x = 0; x < x_size; x++)
        for (y = 0; y < y_size; y++)
            dest_img[y][x_size - 1 -x] = src_img[x][y];

    memcpy(image, dest_img, img_sz);
}

В приложении исходник полностью, но не уверен что соберется не под Линукс.

Тестовое изображение можно взять здесь (Дропбокс, 500 кб)
То что получается лежит здесь (Дропбок, 20кб)
Нужно чтоб получилось изображение повернутое на 90 градусов.

Общий смысл действий
Есть последовательность байт, которая в зависимости от заголовка, интерпретируется особым образом. В моем случае, имеется изображение, размером 600 на 800 пикселей, 8 бит на цвет. Программа пытается сделать поворот, т.е. "певращение" столбцов в исходном изображении, в строки в перевернутом (или наоборот).

Посмотрите пожалуйста на код, может увидите откровенные ляпы, а то у меня уже от этой задачи немного крыша едет, не могу понять где я не правильно делают.

Спасибо.

P.S. Исходник не получилось прикрепить, закинул его на дропбокс
PM MAIL   Вверх
Estranged
Дата 25.9.2011, 22:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 30.8.2010

Репутация: нет
Всего: 3



Функция правильная. Картинка точно на 8 бит?
PM MAIL   Вверх
kurtis
Дата 26.9.2011, 08:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 10.8.2007

Репутация: нет
Всего: нет



точно
размер 480000 байт, это 1 байт (8 бит) * 600 * 800. Именно с этой областью я и работаю.
PM MAIL   Вверх
math64
Дата 26.9.2011, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Код использует возможности C, которых нет в C++ (динамические массивы), поэтому не будет компилироаваться в C++ или компиляторами С, не поддерживающими динамические массивы.
Можно переписать так:
Код

static int rotate_image()
{
    int x_size = info.width; //600
    int y_size = info.height; //800
    int img_sz = x_size*y_size;
    int x, y;
    unsigned char* dest_img = (unsigned char*)malloc(img_sz);
    unsigned char* src_img = (unsigned char*)image;
    for (x = 0; x < x_size; x++)
        for (y = 0; y < y_size; y++)
            dest_img[y * x_size + x_size - 1 - x] = src_img[x  * y_size + y];
    memcpy(image, dest_img, img_sz);
    free(dest_img);
}

PM   Вверх
kurtis
Дата 26.9.2011, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 10.8.2007

Репутация: нет
Всего: нет



Спасибо за предложенный вариант алгоритма, но результат его работы аналогичен приведенному мной. 

Видимо проблема где-то в интерпретации данных bmp файла.
PM MAIL   Вверх
borisbn
Дата 26.9.2011, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(kurtis @  26.9.2011,  11:37 Найти цитируемый пост)
Видимо проблема где-то в интерпретации данных bmp файла.

Может быть... Попробуй сохранить BMP без поворота. Т.е. считать, разобрать по структурам и сохранить. Получаешь исходную картинку ?

Добавлено через 1 минуту и 28 секунд
Может у тебя установлено выравнивание структур на 4 (или 8) байт ? Тогда понятно. Нужно делать на 1 байт


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
math64
Дата 26.9.2011, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Мой вариант делает ровно то же, что и Ваш, но будет компилироваться под C++. Возможно, Вы не оттуда выбираете данные из bmp, В начале идёт заголовок, за ним (при 8-битном изображении) - палитра, и только потом данные, причем сначала нижние строчки. Если строка нечётной длины (не Ваш случай) - добавляется лишний байт для выравнивания.
PM   Вверх
kurtis
Дата 26.9.2011, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 10.8.2007

Репутация: нет
Всего: нет



Цитата(borisbn @ 26.9.2011,  13:02)
Может быть... Попробуй сохранить BMP без поворота. Т.е. считать, разобрать по структурам и сохранить. Получаешь исходную картинку ?

Добавлено @ 13:03
Может у тебя установлено выравнивание структур на 4 (или 8) байт ? Тогда понятно. Нужно делать на 1 байт

md5 хэш полученного изображения полностью совпадает с исходным.

А можно про установку выравнивания немного по подробнее? Из того что я читал, то нужно делать строки кратными 4-м, но в моем случае, это не должно играть особой роли т.к. оба разрешения (исходного и перевернутое) кратны 4-м.


PM MAIL   Вверх
borisbn
Дата 26.9.2011, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(kurtis @  26.9.2011,  13:46 Найти цитируемый пост)
А можно про установку выравнивания немного по подробнее? Из того что я читал, то нужно делать строки кратными 4-м, но в моем случае, это не должно играть особой роли т.к. оба разрешения (исходного и перевернутое) кратны 4-м.

имеется в виду не выравнивание строк изображения, а выравнивание структур в исходном коде.
Не знаю, как в линуксе, а в MSVC это делается так
Код

#pragma pack ( push, 1 )
struct some_struct {
    char x;
    int y;
};
#pragma pack ( pop )

Попробуй, может и для gcc прокатит 


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
kurtis
Дата 26.9.2011, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 10.8.2007

Репутация: нет
Всего: нет



Цитата(math64 @ 26.9.2011,  13:09)
Мой вариант делает ровно то же, что и Ваш, но будет компилироваться под C++. Возможно, Вы не оттуда выбираете данные из bmp, В начале идёт заголовок, за ним (при 8-битном изображении) - палитра, и только потом данные, причем сначала нижние строчки. Если строка нечётной длины (не Ваш случай) - добавляется лишний байт для выравнивания.

На первый взгляд все правильно, т.е. получается получить изображение идентичное исходному. Проблема именно в преобразовании (по крайне мере, мне так кажется).

Добавлено через 6 минут и 26 секунд
Цитата(borisbn @ 26.9.2011,  13:49)
Цитата(kurtis @  26.9.2011,  13:46 Найти цитируемый пост)
А можно про установку выравнивания немного по подробнее? Из того что я читал, то нужно делать строки кратными 4-м, но в моем случае, это не должно играть особой роли т.к. оба разрешения (исходного и перевернутое) кратны 4-м.

имеется в виду не выравнивание строк изображения, а выравнивание структур в исходном коде.
Не знаю, как в линуксе, а в MSVC это делается так
Код

#pragma pack ( push, 1 )
struct some_struct {
    char x;
    int y;
};
#pragma pack ( pop )

Попробуй, может и для gcc прокатит

А, я понял. В GCC есть 
Код

__attribute__ (packed)
 и 
Код

__attribute__ ((aligned(4)))

Спасибо, попробую, хотя не совсем понимаю как это может влиять.
PM MAIL   Вверх
xvr
Дата 26.9.2011, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(kurtis @  25.9.2011,  22:30 Найти цитируемый пост)
   memcpy(src_img, image, img_sz);
...
    memcpy(image, dest_img, img_sz);

А ваш image в курсе, что у него поменялась геометрия после вызова rotate_image()? Было 600х800, а стало 800х600.


PM MAIL   Вверх
kurtis
Дата 26.9.2011, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 10.8.2007

Репутация: нет
Всего: нет



image это двоичные данные, которые интерпретируются в зависимости от заголовка, а в заголовке разрешение я меняю.
PM MAIL   Вверх
math64
Дата 26.9.2011, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Можете попробовать для начала более простые преобразования - например инверсию цвета пикселей. Для проверки, что Вы правильно его находите в bmp.
PM   Вверх
borisbn
Дата 26.9.2011, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(kurtis @  26.9.2011,  13:51 Найти цитируемый пост)
Спасибо, попробую, хотя не совсем понимаю как это может влиять.

sizeof( ваша_структура_заголовка_BMP ) будет отличаться от той, которая записана в файле из-за выравнивания, поэтому структуры должны быть packed

Цитата(math64 @  26.9.2011,  14:36 Найти цитируемый пост)
более простые преобразования - например инверсию цвета пикселей

инверсия цвета в 8-битном BMP - это не совсем простое преобразование. вернее, это не касается самого изображения, а меняется только таблица цветов


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
kurtis
Дата 26.9.2011, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 10.8.2007

Репутация: нет
Всего: нет



Фух. Получилось.  smile 
Правда переделал через одномерный массив. Осталось только понять где накосячил с двухмерными массивами.

Код

unsigned char dest_img[img_sz];//rotated image
unsigned char src_img[img_sz];//source image

for (x = 0; x < x_size; x++)
    for (y = 0; y < y_size; y++)
        dest_img[y + x * y_size] = src_img[(x_size - x - 1)  + y * x_size];


Всем спасибо за помощь и моральную поддержку!
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0584 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.