NAYGER
Участник
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; // высота
???????
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #1 : 02-12-2009 12:57 » |
|
сам не пробовал, но есть функция GetBitmapBits
А ещё, приду домой и попробую вот что: подцепить битмап к HDC , а потом через GetPixel достать точки.
|
|
|
Записан
|
|
|
|
NAYGER
Участник
Offline
|
|
« Ответ #2 : 02-12-2009 12:59 » |
|
Хорошо, буду ждать с нетерпением =)
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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
Участник
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
Участник
Offline
|
|
« Ответ #5 : 03-12-2009 05:51 » |
|
Да, что такое P.S. - Там выше опечатка не MAT[y], а MAT
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #6 : 03-12-2009 06:15 » |
|
NAYGER, это парсер тегов хулиганит )) Когда теги не нужны, а мешают, оберни проблемное место в [ nobbc]...[ /nobbc]
щас прям глянуть не могу, пока занят
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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
Участник
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); - не подходит.
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #9 : 03-12-2009 07:14 » |
|
Только я что-то не понял, как каждый раз записывать в файл с новой строки fputs("\0", file); или fputs("\1", file); - не подходит. перевод строки: fputs("\r\n", file);
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #10 : 03-12-2009 07:21 » |
|
Вад, лучше только "\n", а файл открывать в режиме текста.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
NAYGER
Участник
Offline
|
|
« Ответ #11 : 03-12-2009 07:24 » |
|
Не дописал вопрос: ... как каждый раз записывать в файл с новой строки через строку, т.е.: 10101000110110 10011001010010 10011110011010 P.S. - а что тут написанное сообщение изменять нельзя? И еще, подскажите в какую часть программы вставить код: fputs("\n", file); ? А то куда не поставлю каждый символ в файл записывается с новой строки.
|
|
« Последнее редактирование: 03-12-2009 07:38 от Sel »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #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
Участник
Offline
|
|
« Ответ #13 : 03-12-2009 07:32 » |
|
С постом №11 и №12 разобрался, изв Ините
|
|
« Последнее редактирование: 05-12-2009 05:42 от Sel »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #14 : 03-12-2009 07:34 » |
|
NAYGER, пока редактировать нельзя - чуть позже можно будет.
в "Ответ #7" есть 4 заремленные строчки - если их реализовать, то будет перевод строки вставляться. Ну и учитывай советы RXL и Вада
если нужно через строку - то ещё один перевод вставь
|
|
|
Записан
|
|
|
|
NAYGER
Участник
Offline
|
|
« Ответ #15 : 04-12-2009 10:44 » |
|
Здравствуйте, забыл тогда спросить. Как сделать, чтобы массива изображения записывался сначала в какую-нибудь переменную: Например: M=000000000011110001100110000001100000110000011000001100000111111000000000 А потом эта переменная записывалась в файл. Для того, что бы потом можно было сравнить эту переменную с содержимым файла.
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #16 : 04-12-2009 11:06 » |
|
Создай массив char необходимого размера и указатель на следующую за данными позицию и пиши в эту позицию, передвигая указатель. Потом останется добавить в конец нулевой байт (в длину строки не входит, но место в буфере требует) и можно выводить в файл.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
NAYGER
Участник
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
Пол:
|
|
« Ответ #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
Участник
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
Пол:
|
|
« Ответ #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
Участник
Offline
|
|
« Ответ #21 : 05-12-2009 09:25 » |
|
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
Пол:
|
|
« Ответ #22 : 05-12-2009 10:08 » |
|
if (S==010110010010010010) // [b](1)[/b] Ты уверен, что понимаешь синтаксис C++?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
NAYGER
Участник
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
Пол:
|
|
« Ответ #24 : 05-12-2009 10:47 » |
|
NAYGER, что такое (010110010010010010) у тебя?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
NAYGER
Участник
Offline
|
|
« Ответ #25 : 05-12-2009 10:54 » |
|
Как сделать, чтобы массива изображения записывался сначала в какую-нибудь переменную: Например: M=000000000011110001100110000001100000110000011000001100000111111000000000 А потом эта переменная записывалась в файл. Я же выше писал А это я другой bmp файл подключил: S = 010110010010010010
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #26 : 05-12-2009 11:17 » |
|
NAYGER, если честно, это бред. Лучше остановись, расслабься, пива попей, а через день-два подумай снова. И не торопись писать - сперва почитай самоучитель или что-то вроде по C++.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
NAYGER
Участник
Offline
|
|
« Ответ #27 : 05-12-2009 11:57 » |
|
Попробую по глобальней объяснить проблему, может даст какое-нибудь просветление.
Подключаем bmp изображение, перегоняем его в массив, записываем этот массив в txt файл. Дальше необходимо сравнить массив изображения, с тем что записан в txt. Если строка записанного изображения в txt файле совпадает с массивом изображения, то выводим результат на экран (результатом считается название изображения). Т.е. если мы перегоняем изображение 2-йки (которая была в выше описанном посте), содержимое txt файла будет выглядеть так: 000000000011110001100110000001100000110000011000001100000111111000000000 двойка (этот результат и должен выводиться на экран) //пропускаем строку //записываем новое изображение и т.д.
Если нет совпадений, то пропускаем строку в файле и записываем на следующую массив изображения.
|
|
|
Записан
|
|
|
|
NAYGER
Участник
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 »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #29 : 08-12-2009 04:18 » |
|
Сравнить этот массив с txt файлом, перед записью в txt файл - не сделанно.
а зачем ? Быстрее будет просто очистить файл и записать туда без сравнивания А то это ж надо считать файл, сравнить...
|
|
|
Записан
|
|
|
|
|