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

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

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

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

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

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

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

Вывод на экран содержиоме vector в виде двумерного массива - C++
Создал функцию в которой vector инициализируется значениями передаваемого двумерного массива: void ProcessDoubleArray(double *arr,int...

Вывести на экран в виде матрицы все элементы заданного двумерного массива - C++
Составить программу которая выводит на экран в виде матрицы элементы двумерного массива, состоящего из 5 строки и 3 столбцов. Значения...

Создать программу, которая реализует журнал с оценками в виде двумерного массива - C++
Пишу в Microsoft Visual Studio ->Win32 Console application ->C++. Условие задачи: Создать программу, которая реализует журнал с...

Найти минимальные элементы в каждом столбце произвольного двумерного массива и записать их в виде одномерного - C++
Найти минимальные элементы в каждом столбце произвольного двумерного массива и записать их в виде одномерного массива есть код в c#,...

Как сделать, чтобы при вводе двумерного массива он сразу отображался в виде таблицы? - C++
Желательно использовать оператор setw().

Как правильно записать в виде функции выделение памяти для двумерного массива и ее освобождение - 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'а
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.08.2012, 20:06
Привет! Вот еще темы с ответами:

Данные о ценах в М магазинах для N видов товара хранятся в виде двумерного массива. Сформировать таблицу - C++
вот код,но выскакивает ошибка Run-Time Check Failure #3 - The variable 'i' is being used without being initialized. #include...

Как правильно посмотреть, что находится в массиве пикселей в понятном виде? - C++
Есть камера, с которой в комплекте идет библиотека и её описание с примерами. В одном примере указано: const char* p_buf =...

Ввести элементы двумерного массива с клавы С++.Нужно вывести его на экран в виде таблицы, в конце каждой строки надо вывести самый большой элемент - C++
Вот мой код : #include &lt;iostream&gt; #include &lt;Windows.h&gt; using namespace std; using std::cout; using std::cin; int...

Функции двумерного массива. Транспонировать матрицу через ввод вывод функции двумерного массива. - C++
Транспонировать матрицу через ввод вывод функции двумерного массива.Сначала вывести ее,а потом провести транспонирование.


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
10.08.2012, 20:06
Ответ Создать тему
Опции темы

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