Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.88/74: Рейтинг темы: голосов - 74, средняя оценка - 4.88
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
1

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

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

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

Добавлено через 3 часа 25 минут
Есть идеи? ; (
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.08.2012, 17:32
Ответы с готовыми решениями:

Подсчитать сумму строк двумерного массива и вывести в виде одномерного массива
Подсчитать сумму строк двумерного массива и вывести в виде одномерного массива. Не пойму как...

Представление двумерного массива размерами n*m в виде одномерного массива длиной n*m элементов
Написать программу для представления двумерного массива размерами n*m в виде одномерного массива...

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

Запрашивать размеры двумерного массива, значения его элементов и выводит на экран массива в виде матрицы
помогите решить!!!!!!!! Составьте программу, которая запрашивает размеры двумерного массива,...

23
54 / 48 / 4
Регистрация: 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.
1
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
10.08.2012, 12:11  [ТС] 3
cossack5, да, спасибо, с этим я разобрался. Однако вот "инфернала" не вышло. Добавил лишний байт в картинку и ничего ;< я надеялся, что все байты и вся палитра полетит к чертям, но вышло так, что просто изображение стало более.. синим/красным/зеленым
0
54 / 48 / 4
Регистрация: 02.08.2012
Сообщений: 127
10.08.2012, 12:40 4
Цитата Сообщение от nexen Посмотреть сообщение
cossack5, да, спасибо, с этим я разобрался. Однако вот "инфернала" не вышло. Добавил лишний байт в картинку и ничего ;< я надеялся, что все байты и вся палитра полетит к чертям, но вышло так, что просто изображение стало более.. синим/красным/зеленым
Попробуйте заюзать эти функции http://msdn.microsoft.com/en-u... s.85).aspx. С их помощью можно всячески уродовать изображения.
2
187 / 180 / 25
Регистрация: 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 на эту функцию, то она действительно рандомит каждый пиксель. Числа разные
0
54 / 48 / 4
Регистрация: 02.08.2012
Сообщений: 127
10.08.2012, 17:06 6
а если srand вызывать с самом начале (проги)?

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

Не по теме:

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

0
54 / 48 / 4
Регистрация: 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);
1
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
10.08.2012, 17:49  [ТС] 11
cossack5, неа. Не вышло
0
54 / 48 / 4
Регистрация: 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;
            }
1
187 / 180 / 25
Регистрация: 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), то получается (опять таки) горизонтальный флаг, состоящий из вертикальных рандомных полос О_о
0
6 / 6 / 0
Регистрация: 01.08.2012
Сообщений: 70
10.08.2012, 20:04 14
Возможно, я немного не в тему, но всёже: а почему бы не использовать какую-нибудь библиотеку для работы с картинками? Ведь одними bmp сыт не будешь, есть ещё много хороших форматов - те же jpg и png. Хотя наверно вы это делаете для общего развития.
1
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
10.08.2012, 20:06  [ТС] 15
vampir64, замечание, конечно, дельное, но не к месту. Ибо я делаю просто потому, что хочу увидеть анархию пикселей : > но пока что у меня лишь анархия в мозге из-за "нехотенияработатьsetpixelсовсемникак"
А bmp я взял лишь потому, что мне предложили, да и он распарсивается просто, в отличии от jpeg'а
0
6 / 6 / 0
Регистрация: 01.08.2012
Сообщений: 70
10.08.2012, 20:11 16
Что такое анархия пикселей? Вы хотите исковеркать формат файла и получить на выходе что-то неудобоваримое, которое скорее всего просмотровщик картинок даже не переварит? Я сильно сомневаюсь, что результат будет интересен.
0
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
10.08.2012, 20:21  [ТС] 17
vampir64, как я уже писал выше, мне не нужно его просматривать "просмотрщиком". Достаточно вывести попиксельно.
0
54 / 48 / 4
Регистрация: 02.08.2012
Сообщений: 127
10.08.2012, 20:41 18
Цитата Сообщение от vampir64 Посмотреть сообщение
Что такое анархия пикселей? Вы хотите исковеркать формат файла и получить на выходе что-то неудобоваримое, которое скорее всего просмотровщик картинок даже не переварит? Я сильно сомневаюсь, что результат будет интересен.
Почему же не будет? Можно записать обратно в файл также как и считали.
0
6 / 6 / 0
Регистрация: 01.08.2012
Сообщений: 70
10.08.2012, 20:55 19
cossack5, я не понимаю затею. Если уж играть с файлами по правилам, то не лучше ли обеспечить себе комфорт, используя готовое апи? Я бы, например, для такого рода экспериментов и вовсе использовал скриптовый язык python, на котором просто кодить и легко ставить эксперименты, под который есть куча библиотек, как правило очень простых и удобных в использовании. Хотя если вы просто развлекаетесь самодельным парсингом bmp-шек, то другое дело
1
54 / 48 / 4
Регистрация: 02.08.2012
Сообщений: 127
10.08.2012, 21:01 20
Цитата Сообщение от vampir64 Посмотреть сообщение
cossack5, я не понимаю затею. Если уж играть с файлами по правилам, то не лучше ли обеспечить себе комфорт, используя готовое апи? Я бы, например, для такого рода экспериментов и вовсе использовал скриптовый язык python, на котором просто кодить и легко ставить эксперименты, под который есть куча библиотек, как правило очень простых и удобных в использовании. Хотя если вы просто развлекаетесь самодельным парсингом bmp-шек, то другое дело
Я для этих целей использую GFL SDK - самая мощная библиотека для чтения изображений. Но она сравнительно немаленькая, и не везде хочется возиться с подобными, если нужен только .bmp.
1
10.08.2012, 21:01
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.08.2012, 21:01
Помогаю со студенческими работами здесь

Текстбоксы в виде двумерного массива
Всем доброго времени суток! Необходимо реализовать на Visual C# 2010 следующее: 1 форма: ввод...

Представление одномерного массива в виде двумерного
Как представить одномерный массив в виде двумерного?

Автогенерация лабиринта в виде двумерного массива
День добрый, подскажите как можно автогенерировать лабиринт в виде двумерного массива где 0 это...

Вывод двумерного массива в виде матрицы в консоле
using System; class Program { static void Main(string args) { ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru