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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: (?)Вывод массива на Контекст Устройства  (Прочитано 35220 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
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++ » Записан
Джон
просто
Администратор

de
Offline 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."
Джон
просто
Администратор

de
Offline 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
Специалист

ru
Offline Offline

WWW
« Ответ #3 : 17-09-2003 09:04 » 

Судя по функциям MFC + GDI. Вот весрию MFC определить трудно Улыбаюсь
Кстати, на первый беглый взгляд вроде все правильно.
Записан

Megabyte be with you!
Lex
Специалист

ru
Offline Offline

WWW
« Ответ #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
Специалист

ru
Offline Offline

WWW
« Ответ #6 : 17-09-2003 10:07 » 

samadhi, то, что ты привел, бит на точку. И в этом случае оба твои способа работать не будут.
Записан

Megabyte be with you!
samadhi
Гость
« Ответ #7 : 17-09-2003 10:31 » 

Lex, н-н-е совсем, это всё-таки _байт_ на точку, по крайней мере она объявлена как unsigned char... в любом случае сформировать из него понятное Windows'у монохромное изображение, я думаю, возможно.
Записан
Lex
Специалист

ru
Offline Offline

WWW
« Ответ #8 : 17-09-2003 10:50 » new

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
Специалист

ru
Offline Offline

WWW
« Ответ #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
Специалист

ru
Offline Offline

WWW
« Ответ #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
Специалист

ru
Offline Offline

WWW
« Ответ #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
Специалист

ru
Offline Offline

WWW
« Ответ #17 : 18-09-2003 14:07 » 

Пажалуйста, обращайся еще
Записан

Megabyte be with you!
Джон
просто
Администратор

de
Offline 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-битный целочисленный тип. У меня, почему-то только так получилось. Н-н-е, понимаю :?.
Записан
Джон
просто
Администратор

de
Offline 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
Специалист

ru
Offline Offline

WWW
« Ответ #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
Специалист

ru
Offline Offline

WWW
« Ответ #23 : 19-09-2003 12:00 » 

А поподробнее с объявлением преременных. и как у вас вначале это было
Записан

Megabyte be with you!
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines