samadhi
Гость
|
|
« : 16-09-2003 17:14 » |
|
Непонимаю, что делаю не так. Есть массив unsigned char*, там находится картинка (монохромная), и нужно вывести её на контекст устройства. Вот код, который пробовал я: void CBitmapView::DrawGlyph( int x, int y, int w, int h, // координаты и размеры картинки на экране int W, int H, // реальные размеры const Byte *bitmap, CDC *pDC // сама картинка и контекст устройства ) {
if ( !pDC ) return;
CRect rect( x, y, x + w - 1, y + h - 1 ); if ( !pDC->RectVisible( rect ) ) return;
/* Способ № 1 */ UINT nColorsBits = 8; UINT nColors = 1 << nColorsBits;
HPALETTE hPal = CreateGlyphPalette( nColors );
HPALETTE hOldPal = SelectPalette(pDC->GetSafeHdc(), hPal, TRUE); UINT N = pDC->RealizePalette (); BITMAPINFO *bm = ( BITMAPINFO * )LocalAlloc( LMEM_FIXED, sizeof(BITMAPINFO) + sizeof(WORD) * nColors );
bm->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bm->bmiHeader.biPlanes = 1; bm->bmiHeader.biBitCount = nColorsBits; bm->bmiHeader.biCompression = BI_RGB; bm->bmiHeader.biClrUsed = nColors; bm->bmiHeader.biClrImportant = 0;
bm->bmiHeader.biWidth = W; bm->bmiHeader.biHeight = -H; // картинка прямостояшая bm->bmiHeader.biSizeImage = (DWORD) W * H; bm->bmiHeader.biXPelsPerMeter = (300 * 10000) / 254; bm->bmiHeader.biYPelsPerMeter = (300 * 10000) / 254;
LPWORD pCol = reinterpret_cast<LPWORD>(bm->bmiColors); for (WORD i = 0; i < nColors; i++ ) pCol[i] = i; int n = StretchDIBits(pDC->GetSafeHdc(), x, y, w, h, 0, 0, W, H, (const void*)( bitmap ), bm, DIB_PAL_COLORS, SRCCOPY );
/* ...ну или вот так */
int n = SetDIBitsToDevice( pDC->GetSafeHdc(), x, y, w, h, 0, 0, 0, H, (const void*)( bitmap ), bm, DIB_PAL_COLORS );
/* Способ № 2 */
HBITMAP m_hBitmap = CreateCompatibleBitmap( pDC->GetSafeHdc(), W, H ); int image_size = W*H; ULONG* bitmap_buf = new ULONG [image_size]; for(int i = 0;i<image_size; i++) bitmap_buf[i] = RGB(bitmap[i],bitmap[i],bitmap[i]); LONG n = SetBitmapBits( m_hBitmap, W*H*sizeof ULONG, (VOID *)bitmap_buf );
delete bitmap_buf;
/* ... ну или вот так */ HBITMAP m_hBitmap = CreateBitmap( W, H, 1, nColors, (const void *)bitmap );
HDC hDCMem = CreateCompatibleDC (pDC->m_hDC);
HBITMAP hOldBitmap = (HBITMAP)SelectObject (hDCMem, m_hBitmap);
SetStretchBltMode( pDC->m_hDC, HALFTONE ); StretchBlt (pDC->m_hDC, x, y, w, h, hDCMem, 0, 0, W, H, SRCCOPY);
DeleteObject( (HBITMAP)SelectObject (pDC->m_hDC, hOldBitmap) );
DeleteDC (hDCMem);
SelectPalette( pDC->GetSafeHdc(), hOldPal, FALSE );
DeleteObject( (HPALETTE)hOldPal ); DeleteObject( (HPALETTE)hPal );
LocalFree( (HLOCAL) bm );
}
HPALETTE CBitmapView::CreateGlyphPalette( size_t numcol ) { COLORREF backcolor = RGB(255, 255, 255); COLORREF forecolor = RGB(0, 0, 0); size_t palsize = (sizeof(LOGPALETTE) * (numcol) );// - 1) * // sizeof(PALETTEENTRY)); LPLOGPALETTE pLogPal = reinterpret_cast<LPLOGPALETTE>(new BYTE[palsize]); pLogPal->palVersion = 0x300; pLogPal->palNumEntries = static_cast<WORD>(numcol); pLogPal->palPalEntry[0].peRed = GetRValue(backcolor); pLogPal->palPalEntry[0].peGreen = GetGValue(backcolor); pLogPal->palPalEntry[0].peBlue = GetBValue(backcolor); pLogPal->palPalEntry[0].peFlags = 0; pLogPal->palPalEntry[numcol-1].peRed = GetRValue(forecolor); pLogPal->palPalEntry[numcol-1].peGreen = GetGValue(forecolor); pLogPal->palPalEntry[numcol-1].peBlue = GetBValue(forecolor); pLogPal->palPalEntry[numcol-1].peFlags = 0; for (size_t i = 1; i < numcol - 1; ++ i) { double frac = pow(static_cast<double>(i) / (numcol - 1), 1 ); double r = GetRValue(backcolor); r -= frac * (GetRValue(backcolor) - GetRValue(forecolor)); double g = GetGValue(backcolor); g -= frac * (GetGValue(backcolor) - GetGValue(forecolor)); double b = GetBValue(backcolor); b -= frac * (GetBValue(backcolor) - GetBValue(forecolor));
pLogPal->palPalEntry[i].peRed = static_cast<BYTE>(r + 0.5); pLogPal->palPalEntry[i].peGreen = static_cast<BYTE>(g + 0.5); pLogPal->palPalEntry[i].peBlue = static_cast<BYTE>(b + 0.5); pLogPal->palPalEntry[i].peFlags = 0; }
HPALETTE ret = CreatePalette(pLogPal); delete pLogPal;
return ret;
}
А так же использовал IImgCtx, но результат все равно один и тот же - либо чёрная область (W*H), либо мусор какой-то тех же размеров. Картинку я создаю сам, а не считываю из файла
|
|
« Последнее редактирование: 19-11-2007 19:34 от Алексей1153++ »
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #1 : 17-09-2003 08:57 » |
|
Уй, с первого взгляда не разберёшь. После заполнения ВМР структуры, попробуй сохранить битмап в файл и посмотреть в графическом редакторе. Так можно проверить то, что Гром сказал.
Если картинка нормальная тогда проблемма с выводом.
Вывод можешь проверить так: сделай ВМР ресурс и выведи его по твоему алгоритму.
Ну если совсем ничего, то кричи - поможем
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #2 : 17-09-2003 09:01 » |
|
А кстати, под какой системой дело происходит 6.0 или 7.0? MFC+GDI?
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Lex
|
|
« Ответ #3 : 17-09-2003 09:04 » |
|
Судя по функциям MFC + GDI. Вот весрию MFC определить трудно Кстати, на первый беглый взгляд вроде все правильно.
|
|
|
Записан
|
Megabyte be with you!
|
|
|
Lex
|
|
« Ответ #4 : 17-09-2003 09:28 » |
|
Вопрос первый, как картинка записана в массиве? Побитово или байт на точку?
На сколько я помню, в конце каждой строки в битнапке идут pad байты, для выравнивания строк но границе 4 байт.
|
|
|
Записан
|
Megabyte be with you!
|
|
|
samadhi
Гость
|
|
« Ответ #5 : 17-09-2003 09:48 » |
|
Простите, что забыл упомянуть систему. Lex прав, это MFC 6.0 + GDI. (Win2k на случай предложения GDI+) картинка - байт на точку, выглядит где-то так: 00100 01010 10001 11111 10001 если кто не разобрал это буква "А" Да, ещё, в файл она сохраняется, и все редакторы её понимают, а вот на экран вывести не могу
|
|
|
Записан
|
|
|
|
Lex
|
|
« Ответ #6 : 17-09-2003 10:07 » |
|
samadhi, то, что ты привел, бит на точку. И в этом случае оба твои способа работать не будут.
|
|
|
Записан
|
Megabyte be with you!
|
|
|
samadhi
Гость
|
|
« Ответ #7 : 17-09-2003 10:31 » |
|
Lex, н-н-е совсем, это всё-таки _байт_ на точку, по крайней мере она объявлена как unsigned char... в любом случае сформировать из него понятное Windows'у монохромное изображение, я думаю, возможно.
|
|
|
Записан
|
|
|
|
Lex
|
|
« Ответ #8 : 17-09-2003 10:50 » |
|
samadhi, Нет ты в корне не прав, у тебя в картинке идет 1 бит на точку. Если бы был байт на точку, то вот это: 00000100 00001010 00010001 00011111 00010001 не было бы буквой "А", а было бы 8 точек с разными цветами или яркостями. ТО, что оно у тебя объявлена как unsigned char никоим образом не влияет на количество бит/байт на точку. Ты должен понять, что каждый байт твоей картинки определяет не одну, а 8 точек изображения. Соответствено в первом способе bm->bmiHeader.biClrUsed = nColors; // где nColors = 2 ну и bm->bmiHeader.biSizeImage = (DWORD) W * H / 8; во втором способее for(int i = 0;i<image_size; i++) bitmap_buf[i] = RGB(bitmap[i],bitmap[i],bitmap[i]);
должно быть похоже на что-нить такое for(int i = 0;i<image_size; i++) bitmap_buf[i] = RGB((bitmap[i / 8] << i%8) & 0x80, (bitmap[i / 8] << i%8) & 0x80, (bitmap[i / 8] << i%8) & 0x80);
|
|
« Последнее редактирование: 19-11-2007 19:36 от Алексей1153++ »
|
Записан
|
Megabyte be with you!
|
|
|
samadhi
Гость
|
|
« Ответ #9 : 17-09-2003 12:06 » |
|
Lex, скорее всего я что-то не понимаю, всё-таки младенец ещё . Объявление массива происходит так: typedef unsigned char Byte
Byte *bitmap = new Byte[w*h]; // w, h - рамеры будущей картинки
т.е. как я понимаю на каждый пиксел выделяется 1 байт (256 состояний), сохранить в файл мне удается как 256-цветную картинку. Я может не удачный пример привел, прошу пардона. Я всё равно попробовал твой код - выстраивает в вертикальную цепочку картинку.
|
|
« Последнее редактирование: 19-11-2007 19:37 от Алексей1153++ »
|
Записан
|
|
|
|
Lex
|
|
« Ответ #10 : 17-09-2003 12:13 » |
|
Объявлять картинку можешь как хочешь, лишь бы памяти хватило Сколько у нее бит на пиксел приходиться 1 или 8 зависит от того, как ты ее формируешь. Чтобы окончательно разобраться приведи код, который генерит картинку
|
|
|
Записан
|
Megabyte be with you!
|
|
|
samadhi
Гость
|
|
« Ответ #11 : 17-09-2003 12:46 » |
|
Если поможет... там довольно сложно... читаю из файла, а далее: void PkRasterdata::construct_bitmap() { bitmap_ = new Byte[w_ * h_];
// rasterinfo is a pure bitmap - no decoding necessary unsigned int nbits_req = w_*h_;
Byte *p = bitmap_;
const Byte *r = rasterdata_; // rasterdata_ - прочтённое из файлика
Byte b;
while (nbits_req >= 8) { for (int i=7, bb=*r; i>=0; i--, bb>>=1) p[i] = static_cast<Byte>(bb&1);
p += 8;
r++;
nbits_req -= 8; } if (nbits_req > 0) { // get the last few bits b = static_cast<Byte>(*r >> (8-nbits_req));
for (int i=nbits_req-1; i>=0; i--, b>>=1) p[i] = static_cast<Byte>(b&1); } }
Я еще пробовал выводить в текстовый файл, когда не умел писать bmp: void CTxtBitmap::Write( CString filename, int nWidth, int nHeight, const Byte *bitmap) { CStdioFile file; try { if (!file.Open( filename, CFile::modeCreate | CFile::modeWrite | CFile::typeText )) return; } catch(CException * pE) { pE->Delete(); return; } for ( int i = 0; i < nHeight; i++ ) { CString str; const Byte *p = &bitmap[ i * nWidth ]; for ( int j = 0; j < nWidth; j++ ) {
if ( *(p + j) ) str += "0"; else str += "1";
}
str += "\n"; try { file.WriteString( str ); } catch(CException * pE) { //file.Close(); pE->Delete(); return; }
} file.Close(); }
Э-э-х, трудна и неказиста жизнь простого программиста
|
|
« Последнее редактирование: 19-11-2007 19:41 от Алексей1153++ »
|
Записан
|
|
|
|
Lex
|
|
« Ответ #12 : 17-09-2003 13:21 » |
|
А файл какой читаешь? Как там данные распологаются? Проблема может быть в том, что ширина твоей картинки не кратна 8 и тогда вполе нвероятно, что присутствуют несколько лишних бит в конце каждой строки, дабы строки были выровнены по границе байта.
|
|
|
Записан
|
Megabyte be with you!
|
|
|
samadhi
Гость
|
|
« Ответ #13 : 17-09-2003 14:09 » |
|
это PK-файл - шрифт для TeX/LaTeX. Я могу привести код сохранения в файл. Он выдаёт нужный результат. Bitmap::Bitmap(int nWidth, int nHeight) : m_nWidth(nWidth), m_nHeight(nHeight) {
WORD cClrBits = (WORD)8; max_colour_ = static_cast<BYTE>((1<<cClrBits) - 1); m_lpDIB = (Byte *) GlobalAlloc(GMEM_FIXED, m_nWidth * m_nHeight ); memset(m_lpDIB, max_colour_, m_nWidth * m_nHeight );
m_lpBmpInfoHdr = (LPBITMAPINFOHEADER) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) );
memset (m_lpBmpInfoHdr, 0, sizeof(BITMAPINFOHEADER)); m_lpBmpInfoHdr->biSize = sizeof(BITMAPINFOHEADER); m_lpBmpInfoHdr->biWidth = m_nWidth; m_lpBmpInfoHdr->biHeight = m_nHeight; m_lpBmpInfoHdr->biPlanes = (DWORD)1; m_lpBmpInfoHdr->biBitCount = cClrBits; m_lpBmpInfoHdr->biCompression = BI_RGB; m_lpBmpInfoHdr->biSizeImage = m_nWidth * m_nHeight; m_lpBmpInfoHdr->biClrUsed = (1 << cClrBits);
lpRGB = new RGBQUAD[256];
for(int j = 0; j < 256; j++) { lpRGB[j].rgbRed = j; lpRGB[j].rgbGreen = j; lpRGB[j].rgbBlue = j; lpRGB[j].rgbReserved = 0; }
}
BOOL Bitmap::write( CString strFileName ) { HANDLE hf; BITMAPFILEHEADER hdr; DWORD dwTmp;
// Create the .BMP file. hf = CreateFile((LPTSTR)(LPCTSTR)(strFileName), GENERIC_WRITE, (DWORD) 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL); if (hf == INVALID_HANDLE_VALUE) { AfxMessageBox("write - INVALID_HANDLE_VALUE");
return FALSE; }
memset (&hdr, 0, sizeof(hdr)); hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M" hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 1024; hdr.bfSize = hdr.bfOffBits + sizeof(BYTE) * m_nWidth * m_nHeight + m_nHeight * ((3*m_nWidth) % 4);
// Copy the BITMAPFILEHEADER into the .BMP file. WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), (LPDWORD) &dwTmp, NULL);
// Copy the BITMAPINFOHEADER and RGBQUAD array into the file. WriteFile(hf, (LPVOID) m_lpBmpInfoHdr, sizeof(BITMAPINFOHEADER), (LPDWORD) &dwTmp, ( NULL));
WriteFile( hf, (LPVOID)lpRGB, /*lpBitmapHeader->biClrUsed*/256 * sizeof (RGBQUAD), (LPDWORD)&dwTmp, NULL );
for ( int i = m_nHeight - 1; i >= 0 ; i-- ) {
WriteFile( hf, m_lpDIB+(i*m_nWidth), m_nWidth, &dwTmp, NULL );
WriteFile (hf, lpRGB, (3 * m_nWidth) % 4, &dwTmp, NULL); // забиваем мусором }
CloseHandle(hf);
return TRUE;
}
|
|
« Последнее редактирование: 19-11-2007 19:43 от Алексей1153++ »
|
Записан
|
|
|
|
Lex
|
|
« Ответ #14 : 17-09-2003 17:21 » |
|
Ничего не понимаю. Скинь мне свою прогу на lex@hotmail.ruГде-то у тебя идет путаница с форматами представления твоей картинки
|
|
|
Записан
|
Megabyte be with you!
|
|
|
samadhi
Гость
|
|
« Ответ #15 : 18-09-2003 12:22 » |
|
Lex, это будет тяжеловато сделать, поскольку прога разбитта на библиотечку и саму прогу, кроме того нужно перекачивать шрифты и файлик с dvi - документ. Я попробовал предложенный Джоном вариант, запихнул в ресурс бмп-шку и вывел её - вывод работает, правда, через создание hMemDC (второй способ), что медленнее работает; первый - выдал фантан пикселей . Попытаюсь поиграться с ним.
|
|
|
Записан
|
|
|
|
samadhi
Гость
|
|
« Ответ #16 : 18-09-2003 13:53 » |
|
Эге-ге-е-й, мужики, уменя ПОЛУЧИЛОСЬ . Lex, ты АБСОЛЮТНО прав. Я залез в класс, который сохраняет картинку на диск, биты там объявлены как BYTE в MSDN'е читаю : BYTE - An 8-bit integer that is not signed, а я в перерисовке использовал unsigned char. ПАСИБА!!!
|
|
|
Записан
|
|
|
|
Lex
|
|
« Ответ #17 : 18-09-2003 14:07 » |
|
Пажалуйста, обращайся еще
|
|
|
Записан
|
Megabyte be with you!
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #18 : 18-09-2003 14:48 » |
|
samadhi, рад за тебя, только я теперь нифига не понял - разве BYTE это не то-же самое, что "unsigned char"?
typedef byte BYTE; typedef unsigned char byte;
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
samadhi
Гость
|
|
« Ответ #19 : 18-09-2003 15:47 » |
|
Джон, вообще-то, да char - 8-битный целочисленный тип. У меня, почему-то только так получилось. Н-н-е, понимаю :?.
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #20 : 19-09-2003 07:56 » |
|
Вот и я не понял... "Да есть, друг Горацио, на свете вещи, которые не снились вашим мудрецам"
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Lex
|
|
« Ответ #21 : 19-09-2003 08:47 » |
|
samadhi, ты скорее всего где о потерял unsigned и использовал просто char, который знаковый. BYTE в заголовках объявляется как typedef unsigned char BYTE
|
|
|
Записан
|
Megabyte be with you!
|
|
|
samadhi
Гость
|
|
« Ответ #22 : 19-09-2003 11:48 » |
|
нет, что вы, Бил Гейтс с вами, как такое можно забыть, тогда у меня бы вся длл-ка материлась.
В том классе, где пользую BYTE, я копирую картинку, где-то так:
Берём каждый unsigned char и if (*p) *P=*p;
и всё
|
|
|
Записан
|
|
|
|
Lex
|
|
« Ответ #23 : 19-09-2003 12:00 » |
|
А поподробнее с объявлением преременных. и как у вас вначале это было
|
|
|
Записан
|
Megabyte be with you!
|
|
|
|