| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Создание изображения |
| Автор: Goldberg 23.10.2004, 17:15 |
| Всем доброго времени суток! Наконец-то моя камера нормально заработала. Оказалось, что мне дали старую документацию. Так вот, я получаю изображение в чаровый массив, например char chImage[60000]. В дальнейшем я хочу использовать CImage, говорят, что в нем есть все, что мне необходимо(что именно мне необходимо, долго рассказывать Так вот как реализовать создание изображения, с использованием CImage? Может кто знает где есть примерчик? Ну или просто с чего начать, чисто теоритически, без кода, приведите краткий алгоритм моих дейтсвий. P.S.: Искал и в Яндексе, и в Рамблере, и в Гугле, может плохо искал, но не нашел, честно. |
| Автор: Mad 23.10.2004, 17:27 |
| Сначала создаеш HBITMAP и загружаеш пиксели в него, потом вызаваеш Attach из CImage. |
| Автор: Goldberg 23.10.2004, 17:37 |
| ... |
| Автор: Mad 23.10.2004, 17:53 |
| Goldberg Нет, это вместо Create. HBITMAP надо создать при помощи GDI API. Посмотри CreateBitmap в параметр lpvBits и ставиш свой масив. |
| Автор: Goldberg 23.10.2004, 18:15 |
| CBitmap bmp; bmp.CreateBitmap(600, 600, 256, 12, chReadImage); CImage image; image.Attach(bmp); image.Save("D:\\\aaaaa", ?????????? ); Во втором параметры пишу ImageFormatGIF, говорит undeclared identifier Добавлено @ 18:22 Оказалось можно просто - image.Save("D:\\\aaaaa.gif"); Но все равно что-то делаю ни так, в процессе работы появляются ошибки. |
| Автор: Mad 23.10.2004, 18:26 |
| Goldberg Это консты в файле Gdiplusimaging.h прописанны надо писать Gdiplus::ImageFormatGIF Добавлено @ 18:26 Goldberg Какие ошибки ? |
| Автор: Goldberg 23.10.2004, 18:39 |
| В altimage.h in Line 504 Expression: hBitmap != 0 |
| Автор: Mad 23.10.2004, 18:46 | ||
| Goldberg Это из-за CBitmap. сделай так:
Добавлено @ 18:47 Goldberg Только сейчас обратил внимание 12bpp и размер массива 60000 это к слову, или реальные параметры ? |
| Автор: Goldberg 23.10.2004, 18:52 |
| 12 бит/пиксел Рамер кадра - 93750 байт.(не 60000) Добавлено @ 18:54 CBitmap bmp; bmp.CreateBitmap(600, 600, 1, 12, chReadImage); CImage image; image.Attach(bmp); |
| Автор: Mad 23.10.2004, 18:58 |
| Goldberg Нестыковка получается. Если считать что побайтное выравнивание отсутствует, тогда размер кадра 540000 быйт А с выравниванием вообще 720000 байт Это если кадр 600х600 как ты в функцию пишеш. У тебя в масиве риксы случаем ни чем не упакованны ? |
| Автор: Goldberg 23.10.2004, 19:05 |
| Извиняюсь 250Х250. Ошибок не возникает, но и изображение не сохраняется... Добавлено @ 19:07 CBitmap bmp; bmp.CreateBitmap(250, 250, 1, 12, chReadImage); CImage image; image.Attach(bmp); image.Save("C:\ABC.jpg"); Добавлено @ 19:13 - Команда Set_Mode – код = 0AH Устанавливает биннинг и режим передачи данных камерой MODE BINNING Прореживание Бит/пиксел Разрешение Размер кадра 0 1х1 нет 12 1000х1000 1500000 1 1х1 1:4 8 250х250 250000 2 2х2 нет 12 500х500 375000 3 2х2 1:4 8 125х125 15625 4 4х4 нет 12 250х250 93750 5 4х4 1:2 8 125х125 15625 Устанавливаю MODE 4. Добавлено @ 19:14 Упс. Таблица перекосилась, но понять вроде можно. |
| Автор: Mad 23.10.2004, 19:24 | ||
| Goldberg Вопервы у тебя масив получается не выровненный (pBits надо выравнивать по словам, а не по байтам). Еще меня смущает 12bpp. Дело в том, что в описании CreateBitmap для GDI, pBits описан как указатель на масив 8-битных значений. А в описании CBitmap::CreateBitmap 16-битных значений попробуй так (именно попробуй, сам не могу. GDI+ нема
|
| Автор: Goldberg 23.10.2004, 19:38 |
| Опять же никаких ошибок, а результат нулевой. И вот, что: image --> m_hBitmap 0x0a05071e {unused=??? } HBITMAP__ * --> unused CXX0030: Error: expression cannot be evaluated int Добавлено @ 19:42 BITMAP не создается похоже... |
| Автор: Mad 23.10.2004, 20:10 | ||
Даже пустой файл не создается ? |
| Автор: Mad 23.10.2004, 20:33 | ||
| Кажись разобрался. CreateBitmap понимает тока 1,4,8,16,24,32bpp значит код получится такой:
код не оптимизирован. так на скорую руку. |
| Автор: Goldberg 23.10.2004, 22:00 |
| Я честно говоря еще не понял, что ты там делаешь, но в строчке (unsigned short*)pBits[i] = sr<<10+sg<<5+sb; - cannot convert from 'int' to 'unsigned short *' |
| Автор: Mad 24.10.2004, 13:36 |
| Goldberg Там я пару ошибок исправил |
| Автор: Goldberg 24.10.2004, 14:54 |
| Строчка - (unsigned short)pBits[i] = sr<<10+sg<<5+sb; - по прежнему не хочет работать |
| Автор: Mad 24.10.2004, 15:18 | ||
| Goldberg Со всеми исправлениями выглядет так:
|
| Автор: Goldberg 24.10.2004, 17:35 |
| Нет, все равно не сохраняет, и опять же никаких ошибок не выдает. Что-то в создании БИТМЭПА не правильно: hBitmap 0x10050d33 {unused=??? } HBITMAP__ * unused CXX0030: Error: expression cannot be evaluated int |
| Автор: Mad 25.10.2004, 13:19 |
| Goldberg Вопервых ты в дебагере битмап неправильно смотриш (HBITMAP это не указатель пришли на мыло дфнные одного кадра, посмотрю (хоть GDI+ и нема, но bmp записать должно и без него) |
| Автор: Goldberg 25.10.2004, 15:19 | ||
Что сие есть? |
| Автор: Mad 25.10.2004, 15:29 |
| Goldberg сие есть опечатка , следеут читать данные а именно отот твой чаровый масив (просто запиши его в файл и вышли) |
| Автор: Goldberg 25.10.2004, 16:41 |
| Отослал. |
| Автор: Goldberg 25.10.2004, 18:25 |
| 2Mad Получил??? |
| Автор: Mad 26.10.2004, 12:55 | ||
| Goldberg Да. Посмотрел. Вот такой код переводит массив из 12bpp в 16bpp
Поставил GDI+, и попробовал записать картинку - ноль. Кстати HBITMAP нормально создается. После присоединения его CImage правильно определяет его параметры. Попробуй отказатся от GDI+, и попробовать другую библиотеку, например CxImage, FreeImage (помоему обе на SourceForge были). |
| Автор: Goldberg 26.10.2004, 15:32 |
| Ok. Спасибо! |
| Автор: Goldberg 26.10.2004, 15:55 |
| Тут еще вопросик.) Как сделать массив размером nSize? Ну то есть, например: int nSize = 9375; nSize = nSize * 10; unsigned char chReadImage[nSize]; - Неправильно. Пробовал по разному - не работатет. |
| Автор: chipset 26.10.2004, 15:59 | ||
Вообще то это некорректный синтаксис.. unsigned char i[nSize]; Правда я все равно не уверен.. Вот так делай unsigned char *i; i = new char(nSize); |
| Автор: Mad 26.10.2004, 16:03 | ||
ты наверно имел в виду i = new char[nSize] |
| Автор: Goldberg 26.10.2004, 17:56 | ||||
Это я просто здесь ошибся. Я имел ввиду - unsigned char chReadImage[nSize]; |
| Автор: Mad 27.10.2004, 12:44 | ||
Все равно не правильно. Локальные переменные и массивы выделяються при компиляции из стека, соответственно динамическое указание размера локального массива приведет к переполнению стека. |
| Автор: Goldberg 27.10.2004, 17:11 |
| Странно... int nSize = nGetBlock * 9375; unsigned char* chReadImage = new unsigned char[nSize]; Записывается только 4 байта. |
| Автор: Goldberg 27.10.2004, 21:30 |
| Даже если вот так: unsigned char* chReadImage = new unsigned char[93750]; Результат отличается от: unsigned char chReadImage[93750]; Я в функции чтения данных указываю кол-во байт которые нужно читать, а именно: ReadData(chReadImage, sizeof(chReadImage)); Т.е. получается, что в первом случае sizeof(chReadImage) возвращает размер chReadImage 4. ************************ Сейчас проверил, действительно, sizeof почему-то возвращает - 4. |
| Автор: Mad 28.10.2004, 12:07 | ||||
Вот она и читает тебе 4 байта (длина указателя)
|
| Автор: Goldberg 28.10.2004, 14:36 | ||||
Да, действительно. Как я сам не догодался. Спасибо! |
| Автор: Goldberg 30.10.2004, 17:27 | ||
Еще вопросик появился)
Что в memcpy не правильно? ///////////////////////////////////// На всякий случай: CImage::GetBits Return Value A pointer to the bitmap buffer. If the bitmap is a bottom-up DIB, the pointer points near the end of the buffer. If the bitmap is a top-down DIB, the pointer points to the first byte of the buffer. ///////////////////////////////////// Короче говоря, я получаю указатель на буфер, и пытаюсь записать туда все, что находится в m_pSummFrame. |
| Автор: Mad 30.10.2004, 19:56 | ||
Goldberg
А у тебя получается не DIB Придется тебе из сумарного массива снова делать HBITMAP, и атачить его к другому CImage. |
| Автор: Goldberg 30.10.2004, 20:04 | ||
Стоп-стоп. Все у меня ДИБ.)
CImage::Create: Creates a DIB section bitmap and attaches it to the previously constructed CImage object. Добавлено @ 20:11 При получении указателя никаких проблем не возникает. А вот при попытке записать: Unhandled exception at 0x10216393 (msvcr71d.dll) in Name.exe: 0xC0000005: Access violation reading location 0x00131000. |
| Автор: Goldberg 31.10.2004, 13:04 | ||
Вроде как все начинает работать, но доходит до nByte = 8181, опять возникает описанная мной выше ошибка. В memcpy третий параметр, это кол-во байтов которые нужно копировать, или это номер байта в m_pSummFrame, который нужно копировать? Везде по разному пишут. Придерживаюсь второго варианта, хотя бы потому что цикл выполняется 8181 раз, а в первом случае сразу вылетает ошибка. |
| Автор: Mad 31.10.2004, 19:20 | ||||||
тут ошибка, надо
нетправильно, екокраз первый вариант : кол-во байтов. И еще один лапсус. Ты создаеш палитры из 4096 цветов. Хотя у тебя 16 битной изображение, и цветов в нем 65536 соответственно. К тому же 16,24,32 битные изображения палитру не используют |
| Автор: Goldberg 31.10.2004, 21:29 | ||||
| 1. Хм все равно вылетате та ошибка. 2. Ну тогда должно быть так по идее:
Но увы не работает. Можно эту операция как-нибудь по другому выполнить, без memcpy? Ну например подобное будет эквивалентом memcpy?:
|
| Автор: Mad 1.11.2004, 12:32 | ||
| Goldberg Просто напиши
без всякого цикла. |
| Автор: Goldberg 1.11.2004, 18:10 |
| Ну так нет же... Unhandled exception at 0x10216393 (msvcr71d.dll) in Name.exe: 0xC0000005: Access violation writing location 0x00f6f000. Ну так что, без memcpy никак не обойтись? |
| Автор: Mad 2.11.2004, 11:28 | ||
| Goldberg Проблема не memcpy. без него будет выглядеть так :
Но думаю, что ошибку это не уберет [qoute=MSDN] A pointer to the bitmap buffer. If the bitmap is a bottom-up DIB, the pointer points near the end of the buffer. [/quote] Посмотри в дебагере какой у тебя битмап получается top-down или bottom-up, скорей всего проблемма в этом. |
| Автор: Goldberg 2.11.2004, 15:17 | ||
m_nPitch = -500
Т.е. bottom-up(вроде). Как мне тогда, в начало буфера это дело записать? |
| Автор: Mad 2.11.2004, 15:21 |
| Goldberg pBuf -= img.GetPitch()*img.GetHeight; |
| Автор: Goldberg 2.11.2004, 15:43 | ||
Unhandled exception at 0x004275d5 in Name.exe: 0xC0000005: Access violation writing location 0x00fab6e4. |
| Автор: Mad 3.11.2004, 11:37 | ||||
Goldberg
|
| Автор: Goldberg 3.11.2004, 11:50 | ||||
Ну это да, я уже заметил и исправил. Но все равно Unhandled exception at 0x0041ae74 in Name.exe: 0xC0000005: Access violation writing location 0x00f315c4. Тут что-то еще... |
| Автор: Mad 3.11.2004, 12:03 | ||
| Goldberg попробуй
|
| Автор: Goldberg 3.11.2004, 12:20 | ||||
Пробовал. pBuf = pBuf + (image.GetPitch() * (image.GetHeight() - 1)); pBuf = pBuf + (image.GetPitch() * (image.GetHeight() - 100)); //ради эксперемента Результат тот же |
| Автор: Mad 3.11.2004, 12:31 |
| Goldberg Вышли на мыло полный проект. |
| Автор: Goldberg 3.11.2004, 12:36 | ||
Проект или функцию? Если ф-цию то вот:
|
| Автор: Mad 3.11.2004, 12:42 | ||
| Goldberg Ты тут все вместе перепутал Вопервых используеш один размер и для 12bpp изображения и для 16bpp (а они всетаки разные Добавлено @ 12:48 Goldberg Попробуй заменить эту фугкцию на
|
| Автор: Goldberg 3.11.2004, 12:56 |
| Unhandled exception at 0x10216393 (msvcr71d.dll) in CameraControl.exe: 0xC0000005: Access violation writing location 0x00f319ac. Это уже серьезно... |
| Автор: Goldberg 3.11.2004, 20:37 |
| Mad Послал приватное сообщение. |