Как перевести цветное изображение в 256 градаций серого?
От: DissDoc Россия http://rusgame.isrv.ru
Дата: 12.03.05 15:48
Оценка:
Проблема в следующем... У меня есть контекст изображения HDC image_dc;
Как мне перевести изображение в 256 градаций серого?
Re: Как перевести цветное изображение в 256 градаций серого
От: DaDa Cloun Россия  
Дата: 14.03.05 16:17
Оценка:
Здравствуйте, DissDoc, Вы писали:

DD>Проблема в следующем... У меня есть контекст изображения HDC image_dc;

DD>Как мне перевести изображение в 256 градаций серого?

Ооочень геморойно. Рекомендую уйти от DC и перебраться к HBITMAP, из окторого получить
BITMAPINFO, потом получить буфер изображения (я предполагаю, что оно у тебя 24битное).

Создать свою 256цветную палитру, с градацией серого.

Создать буфер BYTE *buf=new BYTE[(Width+Width%4)*Height]; под 8и битную картинку, где каждый пиксел — есть индекс в палитре.

Структурку для работы с 24битным буфером:
#pragma pack(push,1)
struct BIT24
{
BYTE r,g,b;
}
//или BYTE g,b,r; — я не помю как там.
#pragma pack(pop)

Ну и в цикле перебирать все пикселы 24битной картинки, и приводить их к пикелам 8битной картинки, а по какому принципу — сам думай.

Можно проще: искать функцию, которая сама все это делает =)
Re: Как перевести цветное изображение в 256 градаций серого
От: rus blood Россия  
Дата: 14.03.05 16:49
Оценка: 3 (1)
Здравствуйте, DissDoc, Вы писали:

DD>Проблема в следующем... У меня есть контекст изображения HDC image_dc;

DD>Как мне перевести изображение в 256 градаций серого?


R,G,B от 0 до 255.

H = (77 * R + 28 * G + 150 * B) / 255

(с) MS PhotoEd
Имею скафандр — готов путешествовать!
Re[2]: Как перевести цветное изображение в 256 градаций сер
От: korzhik Россия  
Дата: 14.03.05 16:50
Оценка: 1 (1)
Здравствуйте, rus blood, Вы писали:

RB>Здравствуйте, DissDoc, Вы писали:


DD>>Проблема в следующем... У меня есть контекст изображения HDC image_dc;

DD>>Как мне перевести изображение в 256 градаций серого?


RB>

RB>R,G,B от 0 до 255.

RB>H = (77 * R + 28 * G + 150 * B) / 255

RB>(с) MS PhotoEd

В качестве дополнения: Colour to grey scale conversion
Re: Как перевести цветное изображение в 256 градаций серого
От: Ban001  
Дата: 20.03.05 10:17
Оценка: 3 (1)
Здравствуйте, DissDoc, Вы писали:

DD>Проблема в следующем... У меня есть контекст изображения HDC image_dc;

DD>Как мне перевести изображение в 256 градаций серого?

Перейти к YUV
Y сигнал формируется из RGB сигнала по следующей формуле:
Y = 0.299R + 0.587G + 0.114B
U и V сигналы формируются так:
U = R — Y, а V = B — Y

Если тебе нужно только 256 градаций серого,
то Y-сигнал яркости, то что тебе нужно.
Рассчитай Y для кажной точке по ее RGB.
Это и будет градации церого.

И в догонку обратный переход (из YUV в RGB)
R = Y + U,
B = Y + V,
G = Y — 0.509U — 0.194V
... << RSDN@Home 1.1.3 stable >>
Re: Цветное изображение в серое - код в кармане!
От: vovas Россия  
Дата: 22.09.05 10:53
Оценка: 6 (1)
Здравствуйте, DissDoc, Вы писали:
DD>Как перевести изображение в 256 градаций серого?

такой вот код, который умеет переводить Icon, Bitmap, ImageList в серый цвет. пользуйтесь, кому нужно
//////////////////////////////////////////////////////////////////
typedef struct _PIXEL {
   BYTE r, g, b, empty;
} PIXEL;

//////////////////////////////////////////////////////////////////////
typedef NSCLR_API enum _IMGTYPE {
   TypeBitmap = 1,
   TypeIcon,
   TypeImagelist
} IMGTYPE, *LPIMGTYPE;

//////////////////////////////////////////////////////////////////////
typedef NSCLR_API struct _IMG {
   IMGTYPE eImgType;
   union {
       HBITMAP hBmp;
       HICON   hIcon;
       struct _ImgList {
           int cx;
           int cy;
           HBITMAP hBmp;
           HBITMAP hMask;
           unsigned int uFlag;
           HIMAGELIST hImgListOld;
       } ImgList;
   };
} IMG;

//////////////////////////////////////////////////////////////////////
// create new grayed handle/delete old object
HANDLE Grayed(IMG *pImg, HDC hDC) {
   HANDLE hReturn = NULL;
   BITMAP bmp = {0};
   ICONINFO ii = {0};
   HBITMAP hBmp = NULL;
   PBITMAPINFO pbmi  = {0};
   WORD wClrBits = 0;

   switch (pImg->eImgType) {
       case TypeBitmap:
           hBmp = pImg->hBmp;
           break;
       case TypeImagelist:
           l_hBmp = pImg->ImgList.hBmp;
           break;
       case TypeIcon:
           ::GetIconInfo(pImg->hIcon, &l_ii);
           l_hBmp = ii.hbmColor;
           break;
   }

   ::GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp);
   l_wClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
   if (wClrBits == 1)
       wClrBits = 1;
   else if (wClrBits <= 4)
       wClrBits = 4;
   else if (wClrBits <= 8)
       wClrBits = 8;
   else if (wClrBits <= 16)
       wClrBits = 16;
   else if (wClrBits <= 24)
       wClrBits = 24;
   else
       wClrBits = 32;

   if (wClrBits != 24)
       pbmi = (PBITMAPINFO)::LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*(1<<wClrBits));
   else
       l_pbmi = (PBITMAPINFO)::LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER));

   pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
   pbmi->bmiHeader.biWidth = bmp.bmWidth;
   pbmi->bmiHeader.biHeight = bmp.bmHeight;
   pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
   pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;

   if (wClrBits < 24)
       pbmi->bmiHeader.biClrUsed = (1<<wClrBits);

   pbmi->bmiHeader.biCompression = BI_RGB;
   pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth*wClrBits+31)&~31)/8*pbmi->bmiHeader.biHeight;
   PBYTE pBits = (PBYTE)::LocalAlloc(LPTR, pbmi->bmiHeader.biSizeImage);
   ::GetDIBits(hDC, hBmp, 0, pbmi->bmiHeader.biHeight, pBits, pbmi, DIB_RGB_COLORS);

   BYTE bR, bG, bB, bH;
   int iArraySize = pbmi->bmiHeader.biSizeImage/sizeof(PIXEL);
   PIXEL *ppx = (PIXEL*)pBits;

   for (int i = 0; i < iArraySize; i++) {
       bR = ppx[i].r;
       bG = ppx[i].g;
       bB = ppx[i].b;
       bH = BYTE(bR*0.299 + bG*0.587 + bB*0.114);
       ppx[i].r = ppx[i].g = ppx[i].b = bH;
   }

   l_hBmp = ::CreateDIBitmap(hDC, &pbmi->bmiHeader, CBM_INIT, pBits, pbmi, DIB_RGB_COLORS);

   switch (p_pImg->eImgType) {
       case TypeBitmap:
           hReturn = (HANDLE)hBmp;
           ::DeleteObject((HGDIOBJ)pImg->hBmp);
           break;
       case TypeIcon:
           ::DeleteObject((HGDIOBJ)ii.hbmColor);
           ii.hbmColor = hBmp;
           hReturn = (HANDLE)::CreateIconIndirect(&ii);
           ::DeleteObject((HGDIOBJ)ii.hbmColor);
           ::DeleteObject((HGDIOBJ)ii.hbmMask);
           ::DestroyIcon(pImg->hIcon);
           break;
       case TypeImagelist:
           hReturn = (HANDLE)ImageList_Create(pImg->ImgList.cx, pImg->ImgList.cy, pImg->ImgList.uFlag, 16, 8);
           ImageList_Add((HIMAGELIST)hReturn, hBmp, pImg->ImgList.hMask);
           ::DeleteObject((HGDIOBJ)hBmp);
           ::DeleteObject((HGDIOBJ)pImg->ImgList.hBmp);
           ::DeleteObject((HGDIOBJ)pImg->ImgList.hMask);
           ImageList_Destroy(pImg->ImgList.hImgListOld);
           break;
   }

   if (pbmi) {
       ::LocalFree(pbmi);
       pbmi = NULL;
   }

   if (pBits) {
       ::LocalFree(pBits);
       pBits = NULL;
   }

   return hReturn;
}
Re[2]: Как перевести цветное изображение в 256 градаций сер
От: WinterMute Россия http://yarrr.ru
Дата: 22.09.05 11:11
Оценка: 12 (1)
Здравствуйте, rus blood, Вы писали:

RB>Здравствуйте, DissDoc, Вы писали:


DD>>Проблема в следующем... У меня есть контекст изображения HDC image_dc;

DD>>Как мне перевести изображение в 256 градаций серого?


RB>

RB>R,G,B от 0 до 255.

RB>H = (77 * R + 28 * G + 150 * B) / 255

RB>(с) MS PhotoEd

-- не очень удачная реализация формулы Y = 0.299R + 0.587G + 0.114B -- маленькая точность и делитель 255, хотя лучше сделать его степенью двойки.

Если в качестве делителя взять 65536 (2^16), то получится так:
    typedef unsigned int uint;
    uint Y = ( 19595*R + 38470*G + 7471*B ) >> 16;
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.