Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2 3  Все   Вниз
  Печать  
Автор Тема: Запись BMP изображения в матрицу  (Прочитано 58117 раз)
0 Пользователей и 18 Гостей смотрят эту тему.
NAYGER
Участник

ru
Offline Offline

« : 02-12-2009 12:42 » 

Хотелось бы узнать, как перегнать черно-белое изображение (bmp) размером 32х32 в двумерную матрицу?
Где 1 - черный пиксел, а 0 - белый пиксель.

Код:
//загрузка изображения
HBITMAP hbit = (HBITMAP)::LoadImage(NULL,"1.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
BITMAP bmp;
//можно определить параметры загруженного изображения, вызвав функцию GetObject
  ::GetObject(hbit,sizeof(bmp),&bmp);
int x = bmp.bmWidth; // ширина
int y = bmp.bmHeight; // высота

???????
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 02-12-2009 12:57 » 

сам не пробовал, но есть функция GetBitmapBits


А ещё, приду домой и попробую вот что: подцепить битмап к HDC , а потом через GetPixel достать точки.
Записан

NAYGER
Участник

ru
Offline Offline

« Ответ #2 : 02-12-2009 12:59 » 

Хорошо, буду ждать с нетерпением =)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 02-12-2009 16:27 » 

получилось вот что (правда, у меня файл был 24-битный, но это неважно, я полагаю)

всякие проверки на правильность создания хендлов не сделал, чтоб не замусоривать пример
Код:
	HBITMAP hbit = (HBITMAP)::LoadImage(NULL,"c:\\test.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
BITMAP bmp;

::GetObject(hbit,sizeof(bmp),&bmp);

HDC hdc=0;
{
HWND hwndScreen=0;
HDC hdcScreen=::GetDC(hwndScreen);
hdc=::CreateCompatibleDC(hdcScreen);
::ReleaseDC(hwndScreen,hdcScreen);
}

COLORREF dwd=0;
HBITMAP oldBmp=(HBITMAP)::SelectObject(hdc,hbit);
{
for(int x=0;x<bmp.bmWidth;x++)
{
for(int y=0;y<bmp.bmHeight;y++)
{
dwd=::GetPixel(hdc,x,y);
}
}

}
::SelectObject(hdc,oldBmp);
::DeleteDC(hdc);
hdc=0;

::DeleteObject(hbit);
hbit=0;

Записан

NAYGER
Участник

ru
Offline Offline

« Ответ #4 : 03-12-2009 05:47 » 

Как бы теперь реализовать запись массива изображения в файл, в одну строку, т.е. как связать выше описанный код с тем, что написанно ниже?

Допустим есть изображение размером 8Х9 пикселей

Двойка:
Код:
00000000
00111100
01100110
00000110
00001100
00011000
00110000
01111110
00000000


MAT[8][9]
K=1 - черный пиксель, L=0 - белый пиксель

MAT[y][x]
В моем с лучае это координата пикселя:
MAT[0][0] MAT[0][1] MAT[0][2] MAT[0][3] ... MAT[0][n]
MAT[1][0] MAT[1][1] MAT[1][2] MAT[1][3] ... MAT[1][n]
...
MAT[m][0] MAT[m][1] MAT[m][2] MAT[m][3] ... MAT[m][n]


   
Код:
int L=0;
int K=1;
File *file;
char* file_name = "file.txt";
file = fopen( file_name, "a" ); //открываем файл и дописываем его
char load_string[256]
 
If (MAT[0][0]==K)
MAT[0][0]=K;
fputs( K, file );
fputs( "\K", file ); //переходим на следующую строку и записываем пиксель, если черный то 1, если белый то 0
else
MAT[0][0]=L;
fputs( L, file );
fputs( "\K", file );
 
If (MAT[0][1]==K)
MAT[0][1]=K;
fputs( K, file );
else
MAT[0][1]=L;
fputs( L, file );
 
If (MAT[0][2]==K)
MAT[0][2]=K;
fputs( K, file );
else
MAT[0][2]=L;
fputs( L, file );
 
If (MAT[0][3]==K)
MAT[0][3]=K;
fputs( K, file );
else
MAT[0][3]=L;
fputs( L, file );
 
... //и т.д.
 
fclose( file );

Может как-то легче можно этот код преобразовать Улыбаюсь

То содержисмое файла должно выглядеть, так:
00000000001111000110011000000110000011000001100000 1100000111111000000000
« Последнее редактирование: 03-12-2009 06:13 от Алексей1153++ » Записан
NAYGER
Участник

ru
Offline Offline

« Ответ #5 : 03-12-2009 05:51 » 

Да, что такое  Улыбаюсь
P.S. - Там выше опечатка не MAT[y], а MAT
  • [y]
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 03-12-2009 06:15 » 

NAYGER, это парсер тегов хулиганит )) Когда теги не нужны, а мешают, оберни проблемное место в  [ nobbc]...[ /nobbc]

щас прям глянуть не могу, пока занят
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 03-12-2009 06:23 » 

как сохранить в файл - вышеприведённый код подправить так:

Код:
...
...
for(int y=0;y<bmp.bmHeight;y++)
{
for(int x=0;x<bmp.bmWidth;x++)
{
dwd=::GetPixel(hdc,x,y);

if(dwd!=0)
{
//записать в файл '1'
}
else
{
//записать в файл '0'
}
}

// if(y+1<bmp.bmHeight)
// {
// //записать в файл '\r','\n'
// }
}
...
...

« Последнее редактирование: 03-12-2009 06:26 от Алексей1153++ » Записан

NAYGER
Участник

ru
Offline Offline

« Ответ #8 : 03-12-2009 07:10 » 

Алексей1153++,  респектище вам Улыбаюсь

Код:
	{
for(int y=0;y<bmp.bmHeight;y++)
{
for(int x=0;x<bmp.bmWidth;x++)
{
dwd=::GetPixel(hdc,x,y);

if(dwd!=0)
{
fputs("0", file);
}
else
{
fputs("1", file);
}
}
}

}
Только я что-то не понял, как каждый раз записывать в файл с новой строки  Не понял
fputs("\0", file); или fputs("\1", file); - не подходит.
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 03-12-2009 07:14 » 

Только я что-то не понял, как каждый раз записывать в файл с новой строки  Не понял
fputs("\0", file); или fputs("\1", file); - не подходит.
перевод строки:
fputs("\r\n", file);
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 03-12-2009 07:21 » 

Вад, лучше только "\n", а файл открывать в режиме текста.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
NAYGER
Участник

ru
Offline Offline

« Ответ #11 : 03-12-2009 07:24 » 

Не дописал вопрос:
Цитата
... как каждый раз записывать в файл с новой строки
через строку, т.е.:
10101000110110

10011001010010

10011110011010

P.S. - а что тут написанное сообщение изменять нельзя?

И еще, подскажите в какую часть программы вставить код: fputs("\n", file); ?
А то куда не поставлю каждый символ в файл записывается с новой строки.
« Последнее редактирование: 03-12-2009 07:38 от Sel » Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 03-12-2009 07:31 » 

NAYGER, можно. После 5 набранных постов функция редактирования активируется. Редактировать пост можно в течении двух суток после его создания.
https://forum.shelek.ru/index.php?action=vu-rules#post_p4-1

Поставь fputs("\n", file); после внутреннего цикла по x.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
NAYGER
Участник

ru
Offline Offline

« Ответ #13 : 03-12-2009 07:32 » 

С постом №11 и №12 разобрался, извИните Улыбаюсь
« Последнее редактирование: 05-12-2009 05:42 от Sel » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #14 : 03-12-2009 07:34 » 

NAYGER, пока редактировать нельзя - чуть позже можно будет.


в "Ответ #7" есть 4 заремленные строчки - если их реализовать, то будет перевод строки вставляться. Ну и учитывай советы RXL и Вада

если нужно через строку - то ещё один перевод вставь
Записан

NAYGER
Участник

ru
Offline Offline

« Ответ #15 : 04-12-2009 10:44 » 

Здравствуйте, забыл тогда спросить.

Как сделать, чтобы массива изображения записывался сначала в какую-нибудь переменную:
Например: M=000000000011110001100110000001100000110000011000001100000111111000000000
А потом эта переменная записывалась в файл.
Код:
fputs(M, file);

Для того, что бы потом можно было сравнить эту переменную с содержимым файла.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 04-12-2009 11:06 » 

Создай массив char необходимого размера и указатель на следующую за данными позицию и пиши в эту позицию, передвигая указатель. Потом останется добавить в конец нулевой байт (в длину строки не входит, но место в буфере требует) и можно выводить в файл.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
NAYGER
Участник

ru
Offline Offline

« Ответ #17 : 04-12-2009 11:19 » 

Код:
... указатель на следующую за данными позицию и пиши в эту позицию, передвигая указатель. Потом останется добавить в конец нулевой байт...
Не совсем понятно, как это программно выглядеть будет.

Приблизительно может так будет:
Код:
char M[1000];
int i=0;
...
for(int y=0;y<bmp.bmHeight;y++)
{
for(int x=0;x<bmp.bmWidth;x++)
{
dwd=::GetPixel(hdc,x,y);

if(dwd!=0)
{
int n=1;
                                M[i]=M[i++]
                                M[i]=n;
}
else
{
int k=0;
                                M[i]=M[i++]
                                M[i]=k;
}
}
Прочитал в теме указатели и массивы, не знаю то не то, но возможно запись в файл будет как-то так выглядеть:
Код:
int *PA;
PA = &M[i];
CString X;
X = *PA;
fputs(X, file);
« Последнее редактирование: 04-12-2009 12:05 от NAYGER » Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #18 : 04-12-2009 15:16 » 

NAYGER, форматируй код - это же ужас какой-то...

Выглядеть это будет примерно так:

Код:
char *buffer = new char[(x + 2) * y + 1];
char *next = buffer;

*next = '1';
next++;

*next = '0';
next++;

*next = '\n';
next++;

*next = 0;

puts(buffer);

delete[] buffer;
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
NAYGER
Участник

ru
Offline Offline

« Ответ #19 : 05-12-2009 05:35 » 

RXL,  благодарю, получилось Улыбаюсь


Код:
CString str;
...
for(y=0; y<bmp.bmHeight; y++)
 {
   for(x=0; x<bmp.bmWidth; x++)
    {
char *buffer = new char[(x + 2) * y + 1];
char *next = buffer;

dwd=::GetPixel(hdc, x, y);

if(dwd!=0)

{
*next = '0';
next++;
}
else
{
*next = '1';
next++;
}

str= *buffer;
fputs(str,file);
  }
    }
fputs("\n", file); // пропускаем строку или пишем текст на следующей строке
Вот, кое-что накуролесил, в итоге в файл все записывает правильно, но не совсем.
В этом варианте получается, что в txt файл записывается по одному символу, а надо, чтоб сразу, т.е.:

Сечас получается, если str=0, то 0 записывается в файл, потом если str=1, то 1 записывается после 0, потом если str=1, то 1 записывается после 1 и т.д, в итоге txt файл заполняется как надо.
А как сделать, чтоб str накапливала эти числа и сразу записывалась в файл, т.е. не по одному символу, а целой строкой?


« Последнее редактирование: 05-12-2009 05:41 от Sel » Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #20 : 05-12-2009 08:37 » 

Цитата
Код:
dwd=::GetPixel(hdc, x, y);

if(dwd!=0)

{
*next = '0';
next++;
}
else
{
*next = '1';
next++;
}

str= *buffer;
fputs(str,file);

Код:
*next = ::GetPixel(hdc, x, y) != 0 ? '0' : '1';
next++;

*next = 0;

fputs(buffer, file);
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
NAYGER
Участник

ru
Offline Offline

« Ответ #21 : 05-12-2009 09:25 » new

Код:
CString S;
...
for(y=0;y<bmp.bmHeight;y++)
{
    for(x=0;x<bmp.bmWidth;x++)
        {

char *buffer = new char[(x + 2) * y + 1];
char *next = buffer;

*next = ::GetPixel(hdc, x, y) != 0 ? '0' : '1';
next++;

*next = 0;

S=buffer;
if (S==010110010010010010) // [b](1)[/b]
fputs(S, file);
        }
}

Код уменьшился, файл заполняется правильно, а суть проблеммы осталась Жаль
Специально сделал маленький bmp файл и решил проверить с помощью сравнения (1), в итоге в файл ничего не поступает, надо каким-то образом вынести buffer за цикл и fputs(buffer, file).
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #22 : 05-12-2009 10:08 » 

Цитата
Код:
if (S==010110010010010010) // [b](1)[/b]

Ты уверен, что понимаешь синтаксис C++?  Меня одолевают смутные сомнения
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
NAYGER
Участник

ru
Offline Offline

« Ответ #23 : 05-12-2009 10:37 » 

Код:
if (S==010110010010010010) // [b](1)[/b]
fputs(S, file);
А что тут не понятного?  Улыбаюсь

Если S = 010110010010010010, то выводим результат в файл.
После // это коммент.

Мне не понятно, как сделать, чтоб сравнение работало.
По идее, S, или buffer, равно числу 010110010010010010, значит, и сравнение должно сработать, т. к. сравнение производится с этим же числом.
А в цикле, похоже, получается, что сначалА сравнивается:
0=010110010010010010
1=010110010010010010
0=010110010010010010
1=010110010010010010
1=010110010010010010
и т.д.
« Последнее редактирование: 05-12-2009 10:46 от Sel » Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #24 : 05-12-2009 10:47 » 

NAYGER, что такое (010110010010010010) у тебя?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
NAYGER
Участник

ru
Offline Offline

« Ответ #25 : 05-12-2009 10:54 » 

Цитата
Как сделать, чтобы массива изображения записывался сначала в какую-нибудь переменную:
Например: M=000000000011110001100110000001100000110000011000001100000111111000000000
А потом эта переменная записывалась в файл.
Я же выше писал  Улыбаюсь
А это я другой bmp файл подключил:
S = 010110010010010010
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #26 : 05-12-2009 11:17 » 

NAYGER, если честно, это бред. Лучше остановись, расслабься, пива попей, а через день-два подумай снова. И не торопись писать - сперва почитай самоучитель или что-то вроде по C++.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
NAYGER
Участник

ru
Offline Offline

« Ответ #27 : 05-12-2009 11:57 » 

Попробую по глобальней объяснить проблему, может даст какое-нибудь просветление.

Подключаем bmp изображение, перегоняем его в массив, записываем этот массив в txt файл. Дальше необходимо сравнить массив изображения, с тем что записан в txt.
Если строка записанного изображения в txt файле совпадает с массивом изображения, то выводим результат на экран (результатом считается название изображения).
Т.е. если мы перегоняем изображение 2-йки (которая была в выше описанном посте), содержимое txt файла будет выглядеть так:
000000000011110001100110000001100000110000011000001100000111111000000000
двойка (этот результат и должен выводиться на экран)
//пропускаем строку
//записываем новое изображение и т.д.

Если нет совпадений, то пропускаем строку в файле и записываем на следующую массив изображения.
Записан
NAYGER
Участник

ru
Offline Offline

« Ответ #28 : 08-12-2009 04:11 » 

Ну так что, поможЕте доделать программку?

Вот, построчно описал задачи:
Подключить bmp изображение - сделано.
Перегнать bmp изображение в массив - сделано.
Запись этого массива в txt файл - сделано.
Код:
{
CString n, k; // n - пустая строка, k - название изображения
int x,y;

FILE *file;
file = fopen("file.txt", "a");

HBITMAP hbit = (HBITMAP)::LoadImage(NULL,"2.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);  
BITMAP bmp;

::GetObject(hbit,sizeof(bmp),&bmp);

HDC hdc=0;
{
HWND hwndScreen=0;
HDC hdcScreen=::GetDC(hwndScreen);
hdc=::CreateCompatibleDC(hdcScreen);
::ReleaseDC(hwndScreen,hdcScreen);
}
COLORREF dwd=0;
HBITMAP oldBmp=(HBITMAP)::SelectObject(hdc,hbit);
{
for(y=0;y<bmp.bmHeight;y++)
{
for(x=0;x<bmp.bmWidth;x++)
{

char *buffer = new char[(x + 2) * y + 1];
char *next = buffer;

*next = ::GetPixel(hdc, x, y) != 0 ? '0' : '1';
next++;
*next = 0;

fputs(buffer, file);
}
}

UpdateData(true);
k=edit; // вводим название изображения
UpdateData(false);
fputs("\n", file);  // пропускаем строку или пишем текст на следующей строке
fputs(":", file); //записываем знак : в начале строки
fputs(k, file); //записываем введенное название изображения в txt файл
fputs("\n", file); //пропускаем строку в txt файле
fputs("\n", file); //пропускаем строку в txt файле

}
fclose(file);
::SelectObject(hdc,oldBmp);
::DeleteDC(hdc);
hdc=0;

::DeleteObject(hbit);
hbit=0;
}

Сравнить этот массив с txt файлом, перед записью в txt файл - не сделано.
   Если файл пустой или массив не равен строкам из txt файла, произвести запись в txt файл - не сделано.
   Если файл не пустой, производим сравнение массива со строками в txt файле, если массив равен строке, выводим в поле satatic результат на следующей строке после знака ( : ) - почти сделано:
Код:
FILE *mFile;
char f1[10000], f2[10000];
const char *N = "789"; //вместо N будет массив изображения
mFile = fopen ("file.txt","r");
if (mFile !=0)
{    
while (fscanf(mFile, "%s\n:%s\n", f1, f2) == 2)
{
if (!strcmp(f1, N)) //посимвольное сравнение строк
{
UpdateData(true);        
S=f2; //вывод результата в поле static
UpdateData(false);
}
}
}
fclose(mFile);
}
« Последнее редактирование: 08-12-2009 06:44 от Sel » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #29 : 08-12-2009 04:18 » 

Цитата
Сравнить этот массив с txt файлом, перед записью в txt файл - не сделанно.
а зачем ? Быстрее будет просто очистить файл и записать туда без сравнивания Улыбаюсь А то это ж надо считать файл, сравнить...

Записан

Страниц: [1] 2 3  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines