Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 27, средняя оценка - 4.78
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
#1

Картинка в виде двумерного массива пикселей - C++

09.08.2012, 17:32. Просмотров 3670. Ответов 23
Метки нет (Все метки)

Можно ли, засунув картинку в проект, получить её массив пикселей? Есть ли для этого какая-либо функция?
Всё, что мне хочется, это взять картинку, формат которой предусматривает запись информации о пикселях последовательностями в 3 байта (без промежуточной информации) и засунуть туда лишний байт >:- E *хочу инфернальные картинки!!1*

Добавлено через 3 часа 25 минут
Есть идеи? ; (
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.08.2012, 17:32     Картинка в виде двумерного массива пикселей
Посмотрите здесь:

C++ Создать программу, которая реализует журнал с оценками в виде двумерного массива
Найти номер строки и столбца двумерного массива для минимального элемента этого массива C++
Вывод на экран содержиоме vector в виде двумерного массива C++
Ввести элементы двумерного массива с клавы С++.Нужно вывести его на экран в виде таблицы, в конце каждой строки надо вывести самый большой элемент C++
Как правильно записать в виде функции выделение памяти для двумерного массива и ее освобождение C++
Найти минимальные элементы в каждом столбце произвольного двумерного массива и записать их в виде одномерного C++
Данные о ценах в М магазинах для N видов товара хранятся в виде двумерного массива. Сформировать таблицу C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
cossack5
54 / 48 / 1
Регистрация: 02.08.2012
Сообщений: 127
10.08.2012, 12:04     Картинка в виде двумерного массива пикселей #2
Какую именно картинку вы хотите загрузить? если простой битмап (формат .bmp), то нужно считать заголовок сначала, затем пиксели.
Формат битмапа:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
typedef struct tagBITMAPINFOHEADER {
  DWORD biSize;
  LONG  biWidth;
  LONG  biHeight;
  WORD  biPlanes;
  WORD  biBitCount;
  DWORD biCompression;
  DWORD biSizeImage;
  LONG  biXPelsPerMeter;
  LONG  biYPelsPerMeter;
  DWORD biClrUsed;
  DWORD biClrImportant;
}BITMAPINFOHEADER, *PBITMAPINFOHEADER;
Читать можно так (для винды):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <windows.h>
bool ReadBMP24bit(char* Name,BITMAPINFOHEADER* BM,BYTE** data){
HANDLE H=CreateFile(Name,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    if(f1!=INVALID_HANDLE_VALUE){
        RBlockRead(f1,BM,sizeof BMPformat);
        if(IOresult()||BM->bfType!='MB')return false;
        if(BM->biBitCount!=24)return false;
        *data=new BYTE(byte,BM->biWidth*BM->biHeight*3);
        int wid=BM->biWidth*3;
        int rwid=wid;
        if(wid&3)rwid=(wid|3)+1;
        for(int i=0;i<BM->biHeight;i++){
            RSeek(f1,(sizeof BMPformat)+(BM->biHeight-i-1)*rwid);
            RBlockRead(f1,&((*data)[i*wid]),wid);
        };
        CloseHandle(H);
        return true;
    }else return false;
};
Загружаем так:
C++
1
2
3
BYTE* data;
BITMAPINFOHEADER BM;
ReadBMP24Bit("C:\\Games\\picture.bmp",&BM,&data);
Дальше можно работать с массивом data (изменять пиксели и т.д.). Функция на примере загружает 24 битные изображения только, но можно переписать код и для 32 или 16

Добавлено через 12 часов 26 минут
У меня там опечка: вместо BMPformat должно быть BITMAPINFOHEADER.
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
10.08.2012, 12:11  [ТС]     Картинка в виде двумерного массива пикселей #3
cossack5, да, спасибо, с этим я разобрался. Однако вот "инфернала" не вышло. Добавил лишний байт в картинку и ничего ;< я надеялся, что все байты и вся палитра полетит к чертям, но вышло так, что просто изображение стало более.. синим/красным/зеленым
cossack5
54 / 48 / 1
Регистрация: 02.08.2012
Сообщений: 127
10.08.2012, 12:40     Картинка в виде двумерного массива пикселей #4
Цитата Сообщение от nexen Посмотреть сообщение
cossack5, да, спасибо, с этим я разобрался. Однако вот "инфернала" не вышло. Добавил лишний байт в картинку и ничего ;< я надеялся, что все байты и вся палитра полетит к чертям, но вышло так, что просто изображение стало более.. синим/красным/зеленым
Попробуйте заюзать эти функции http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx. С их помощью можно всячески уродовать изображения.
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
10.08.2012, 16:56  [ТС]     Картинка в виде двумерного массива пикселей #5
cossack5, спасибо конечно, но мне по сути нужно не изуродовать изображение, а сделать другое, с данными из первого. Думаю придется при получении массива пикселей поработать, а затем уже вывести на экран не через bmp, а через SetPixel

Добавлено через 3 часа 26 минут
Вот что я сделал :
1) Считал по байтам bmp формат, пока не дошел до самой матрицы пикселей.
2) Считал матрицу и записал в отдельный двоичный файл
// 3) Считал матрицу и вывел SetPixel'ем, чтобы убедиться, что в дв. файле теперь только матрица пикселей.
3) Вывел матрицу пикселей на экран, добавив в начало один лишний байт и удалив из конца один байт, на который я сместил всё это дело.

PROFIT :
<Ожидание> Chaos, Anarchy, Sodomy.
<Реальность> То же самое изображение.. Возможно в углу есть испорченный один бит, но этого я не разглядел

ВОПРОС :
Как сделать ожидание реальностью?

<Bonus> Сделал рандомизацию пикселей типа :
C++
1
2
3
4
5
6
7
8
RGBTRIPLE* RandRGB(RGBTRIPLE color)
{
    srand(static_cast<unsigned int>(time(NULL)));
    color.rgbtBlue = rand()%256;
    color.rgbtGreen = rand()%256;
    color.rgbtRed = rand()%256;
    return &color;
}
Всё равно не работает так, как должна.
<Ожидание> Chaos из разноцветных пикселей
<Реальность> ..Флаг.. Выводятся горизонтальные полосы в высоту, примерно, по 200 пикселей разных цветов. При этом эти цвета похожи (одного оттенка) : красный, оранжевый, желтый, светло-зеленый и т.д (плавный переход). Причем они сами повторяются через 4 полосы. Вот пример такого :Картинка в виде двумерного массива пикселей
Сам флаг при каждом новом запуске разных цветов :<
p.s Если ставить breakpoint на эту функцию, то она действительно рандомит каждый пиксель. Числа разные
cossack5
54 / 48 / 1
Регистрация: 02.08.2012
Сообщений: 127
10.08.2012, 17:06     Картинка в виде двумерного массива пикселей #6
а если srand вызывать с самом начале (проги)?

Добавлено через 3 минуты
Можете показать код вывода точек/пикселей?
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
10.08.2012, 17:09  [ТС]     Картинка в виде двумерного массива пикселей #7
cossack5, да как об стенку горох ; (

Добавлено через 57 секунд
C++
1
2
3
4
5
6
7
8
for (int i=0; i<sx; ++i)
                for (int j=0; j<sy; ++j)
                {
                    fread(&rgb_l, sizeof(rgb_l), 1, f2);
                    //srand(time(NULL));
                    //rgb_l = *RandRGB(rgb_l);
                    SetPixel(hdc, j, sx-1-i, RGB(rgb_l.rgbtRed, rgb_l.rgbtGreen, rgb_l.rgbtBlue));
                }
Пришлось немного похимичить с i и j из-за того, что изначально они храняться в выводе с другой системой координат

Добавлено через 36 секунд
Такое "химичинье" проверено на выводе простого изображение, так что с ним все впорядке
cossack5
54 / 48 / 1
Регистрация: 02.08.2012
Сообщений: 127
10.08.2012, 17:16     Картинка в виде двумерного массива пикселей #8
Как я понял, этот пример работает? а с RandRGB нет? так?
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
10.08.2012, 17:27  [ТС]     Картинка в виде двумерного массива пикселей #9
Цитата Сообщение от cossack5 Посмотреть сообщение
Как я понял, этот пример работает? а с RandRGB нет? так?
Этот пример работает (выводит первоначальное изображение), а при RandRGB выводит "флаг". Помимо этого не работает смещение на байт для "хаоса". Вот ^^

Не по теме:

p.s Передавай привет Юно

cossack5
54 / 48 / 1
Регистрация: 02.08.2012
Сообщений: 127
10.08.2012, 17:35     Картинка в виде двумерного массива пикселей #10
C++
1
2
3
4
5
6
7
8
9
void RandRGB(RGBTRIPLE* color)
{
    srand(time(nullptr));
    color->rgbtBlue = rand()%255;
    color->rgbtGreen = rand()%255;
    color->rgbtRed = rand()%255;
}
// преобразуем цвета
 RandRGB(&rgb_l);
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
10.08.2012, 17:49  [ТС]     Картинка в виде двумерного массива пикселей #11
cossack5, неа. Не вышло
cossack5
54 / 48 / 1
Регистрация: 02.08.2012
Сообщений: 127
10.08.2012, 19:29     Картинка в виде двумерного массива пикселей #12
а если сделать так, то все работает как надо:
C++
1
2
3
4
5
6
7
8
9
10
11
12
case WM_PAINT:
            {
            HDC hdc=BeginPaint(hwnd,&PS);
            srand(time(nullptr));
            RECT rect;
            GetWindowRect(hwnd,&rect);
            for (int x=0;x<rect.right;x++)
                for (int y=0;y<rect.bottom;y++)
                    SetPixel(hdc,x,y,RGB(rand()%255,rand()%255,rand()%255)); 
            EndPaint(hwnd,&PS);
            return 0;
            }
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
10.08.2012, 20:00  [ТС]     Картинка в виде двумерного массива пикселей #13
cossack5, да, такое работает, но в чем же тогда проблема? О_о

Добавлено через 12 минут
Опаньки. И правда. Если написать в моём варианте вместо :
C++
1
2
3
4
5
6
7
8
for (int i=0; i<sx; ++i)
                for (int j=0; j<sy; ++j)
                {
                    fread(&rgb_l, sizeof(rgb_l), 1, f2);
                    RandRGB(&rgb_l);
                    //SetPixel(hdc, j, sx-i, RGB(rgb_l.rgbtRed, rgb_l.rgbtGreen, rgb_l.rgbtBlue));
                    SetPixel(hdc, j, sx-i, RGB(rand()%255, rand()%255, rand()%255));
                }
это :
C++
1
2
3
4
5
6
7
8
for (int i=0; i<sx; ++i)
                for (int j=0; j<sy; ++j)
                {
                    //fread(&rgb_l, sizeof(rgb_l), 1, f2);
                    //RandRGB(&rgb_l);
                    //SetPixel(hdc, j, sx-i, RGB(rgb_l.rgbtRed, rgb_l.rgbtGreen, rgb_l.rgbtBlue));
                    SetPixel(hdc, j, sx-i, RGB(rand()%255, rand()%255, rand()%255));
                }
То работает нормально. Но как такое может быть? О_о
Чем SetPixel'ю помешала fread и RandRGB, если они никак не влияют на rand()? Или влияют?

Добавлено через 1 минуту
Если перенести
C++
1
2
fread(&rgb_l, sizeof(rgb_l), 1, f2);
                    RandRGB(&rgb_l);
на цикл ниже к i<sx-циклу (удалив его перед SetPixel), то получается (опять таки) горизонтальный флаг, состоящий из вертикальных рандомных полос О_о
vampir64
6 / 6 / 0
Регистрация: 01.08.2012
Сообщений: 70
10.08.2012, 20:04     Картинка в виде двумерного массива пикселей #14
Возможно, я немного не в тему, но всёже: а почему бы не использовать какую-нибудь библиотеку для работы с картинками? Ведь одними bmp сыт не будешь, есть ещё много хороших форматов - те же jpg и png. Хотя наверно вы это делаете для общего развития.
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
10.08.2012, 20:06  [ТС]     Картинка в виде двумерного массива пикселей #15
vampir64, замечание, конечно, дельное, но не к месту. Ибо я делаю просто потому, что хочу увидеть анархию пикселей : > но пока что у меня лишь анархия в мозге из-за "нехотенияработатьsetpixelсовсемникак"
А bmp я взял лишь потому, что мне предложили, да и он распарсивается просто, в отличии от jpeg'а
vampir64
6 / 6 / 0
Регистрация: 01.08.2012
Сообщений: 70
10.08.2012, 20:11     Картинка в виде двумерного массива пикселей #16
Что такое анархия пикселей? Вы хотите исковеркать формат файла и получить на выходе что-то неудобоваримое, которое скорее всего просмотровщик картинок даже не переварит? Я сильно сомневаюсь, что результат будет интересен.
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
10.08.2012, 20:21  [ТС]     Картинка в виде двумерного массива пикселей #17
vampir64, как я уже писал выше, мне не нужно его просматривать "просмотрщиком". Достаточно вывести попиксельно.
cossack5
54 / 48 / 1
Регистрация: 02.08.2012
Сообщений: 127
10.08.2012, 20:41     Картинка в виде двумерного массива пикселей #18
Цитата Сообщение от vampir64 Посмотреть сообщение
Что такое анархия пикселей? Вы хотите исковеркать формат файла и получить на выходе что-то неудобоваримое, которое скорее всего просмотровщик картинок даже не переварит? Я сильно сомневаюсь, что результат будет интересен.
Почему же не будет? Можно записать обратно в файл также как и считали.
vampir64
6 / 6 / 0
Регистрация: 01.08.2012
Сообщений: 70
10.08.2012, 20:55     Картинка в виде двумерного массива пикселей #19
cossack5, я не понимаю затею. Если уж играть с файлами по правилам, то не лучше ли обеспечить себе комфорт, используя готовое апи? Я бы, например, для такого рода экспериментов и вовсе использовал скриптовый язык python, на котором просто кодить и легко ставить эксперименты, под который есть куча библиотек, как правило очень простых и удобных в использовании. Хотя если вы просто развлекаетесь самодельным парсингом bmp-шек, то другое дело
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.08.2012, 21:01     Картинка в виде двумерного массива пикселей
Еще ссылки по теме:

Оформить обработку одномерного и двумерного массивов в виде функции C++
C++ Как сделать, чтобы при вводе двумерного массива он сразу отображался в виде таблицы?
Как правильно посмотреть, что находится в массиве пикселей в понятном виде? C++
Из массива пикселей сформировать bmp изображение C++
Вывести на экран в виде матрицы все элементы заданного двумерного массива C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
cossack5
54 / 48 / 1
Регистрация: 02.08.2012
Сообщений: 127
10.08.2012, 21:01     Картинка в виде двумерного массива пикселей #20
Цитата Сообщение от vampir64 Посмотреть сообщение
cossack5, я не понимаю затею. Если уж играть с файлами по правилам, то не лучше ли обеспечить себе комфорт, используя готовое апи? Я бы, например, для такого рода экспериментов и вовсе использовал скриптовый язык python, на котором просто кодить и легко ставить эксперименты, под который есть куча библиотек, как правило очень простых и удобных в использовании. Хотя если вы просто развлекаетесь самодельным парсингом bmp-шек, то другое дело
Я для этих целей использую GFL SDK - самая мощная библиотека для чтения изображений. Но она сравнительно немаленькая, и не везде хочется возиться с подобными, если нужен только .bmp.
Yandex
Объявления
10.08.2012, 21:01     Картинка в виде двумерного массива пикселей
Ответ Создать тему
Опции темы

Текущее время: 00:38. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru