请问 GDI+ 中如何将一个图片保存成8位色,望赐教! 如题。Thanks. 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 void CDib::ConvertToGray (){ if ((this->GetHandle() == NULL) || this->IsGrayPalette ()) return ; if (this->ColorBits() <= 8) { int nNum = 1 << this->ColorBits() ; RGBQUAD * palette = new RGBQUAD[nNum] ; this->GetColorTable (0, nNum, palette) ; if (this->ColorBits() <= 4) // <= 4, 只修改调色板 { for (int i=0 ; i < nNum ; i++) ::FillMemory (&palette[i], 3, FCDib::fooGetGrayscale (palette[i])) ; this->SetColorTable (0, nNum, palette) ; } else // == 8 bit, 修改调色板和索引 { for (int i=0 ; i < nNum ; i++) palette[i].rgbBlue = FCDib::fooGetGrayscale (palette[i]) ; // 修改索引 for (int y=0 ; y < (int)this->Height() ; y++) { BYTE * pLine = this->GetBits (y) ; for (int x=0 ; x < (int)this->Width() ; x++, pLine++) *pLine = palette[*pLine].rgbBlue ; } this->SetGrayPalette () ; } delete[] palette ; return ; } // >= 16 bit color CDib OldDib (* (FCDib *) this) ; // 保存原始数据 int nSpan = OldDib.ColorBits() / 8 ; if (this->Create (OldDib.Width(), OldDib.Height(), 8)) // gray palette setted in create for (int y=0 ; y < (int)this->Height() ; y++) { BYTE * pDest = this->GetBits (y) ; BYTE * pSrc = OldDib.GetBits (y) ; for (int x=0 ; x < (int)this->Width() ; x++, pSrc += nSpan) *pDest++ = FCDib::fooGetGrayscale (OldDib.ParsePixelData (OldDib.__GetPixelData (pSrc))) ; }} HBITMAP CDib::GetDDB_Handle (HDC hdc){ BITMAPINFOHEADER * pbmfh ; int nNum = 1 << this->ColorBits() ; HBITMAP hBitmap ; bool bCreate = false ; if (this->GetHandle() == NULL) return NULL ; if (hdc == NULL) { hdc = ::CreateDC (TEXT("DISPLAY"), NULL, NULL, NULL) ; bCreate = true ; } pbmfh = (BITMAPINFOHEADER *) new BYTE [sizeof(BITMAPV4HEADER) + ((ColorBits() <= 8) ? (nNum * 4) : 0)] ; CopyMemory (pbmfh, &m_DibInfo, sizeof(BITMAPV4HEADER)) ; pbmfh->biSize = sizeof(BITMAPINFOHEADER) ; // 8 位以下色设置调色板 if (this->ColorBits() <= 8) this->GetColorTable (0, nNum, (RGBQUAD *)(pbmfh + 1)) ; hBitmap = CreateDIBitmap (hdc, (BITMAPINFOHEADER *)pbmfh, CBM_INIT, (VOID *)m_pByte, (BITMAPINFO *)pbmfh, DIB_RGB_COLORS) ; delete[] pbmfh ; if (bCreate) ::DeleteDC (hdc) ; return hBitmap ;} RGBQUAD FCDib::ParsePixelData (DWORD dwData) const{ RGBQUAD rgb = {0, 0, 0, 0} ; switch (this->ColorBits()) { case 1 : case 4 : case 8 : this->GetColorTable ((int)dwData, &rgb) ; break ; case 16 : if (m_DibInfo.bV4V4Compression == BI_RGB) rgb = fooSplit16Bit_555 ((WORD)dwData) ; else if (m_DibInfo.bV4GreenMask == MASK16_GREEN_555) rgb = fooSplit16Bit_555 ((WORD)dwData) ; else rgb = fooSplit16Bit_565 ((WORD)dwData) ; break ; case 24 : case 32 : return * (RGBQUAD *) &dwData ; } return rgb ;}//===================================================================BOOL FCDib::SetColorTable (int iFirstIndex, int iNumber, RGBQUAD * pColors){ if ((this->GetHandle() == NULL) || (this->ColorBits() > 8) || (pColors == NULL)) return FALSE ; HDC hdcMem = CreateCompatibleDC (NULL) ; HBITMAP hBitmap = (HBITMAP) SelectObject (hdcMem, this->GetHandle()) ; BOOL bReturn = (BOOL)::SetDIBColorTable (hdcMem, iFirstIndex, iNumber, pColors) ; SelectObject (hdcMem, hBitmap) ; DeleteDC (hdcMem) ; return bReturn ;} 我是说在 GDI+ 中,而且要保存成 PNG 呢。不过还是感谢楼上兄弟。自己UP。 GDI+中文件格式好象都是32位的,可能得自己做了 CreateProcess创建了一个文件,怎么老删不掉 命令行参数传递与解析 大家来给我点建议好吗? 怎么对表单视图操作? 傻瓜问题 求解 如果把DIALOG的BORDER去掉 vc 在access中插入一条有时间字段的语句的问题? 请问作图问题. 请教一个 SetWindowsHookEx 函数的问题 文件关联及打开文件的调用 我在CEditView::OnCreate()中,btn.Create("hi",WS_CHILD|WS_VISIBLE,CRect(50,50,100,100),&GetEditCtrl(),1001); 写静态库时,C和C++混用的问题 高手帮忙~~~~~
{
if ((this->GetHandle() == NULL) || this->IsGrayPalette ())
return ; if (this->ColorBits() <= 8)
{
int nNum = 1 << this->ColorBits() ;
RGBQUAD * palette = new RGBQUAD[nNum] ;
this->GetColorTable (0, nNum, palette) ;
if (this->ColorBits() <= 4) // <= 4, 只修改调色板
{
for (int i=0 ; i < nNum ; i++)
::FillMemory (&palette[i], 3, FCDib::fooGetGrayscale (palette[i])) ;
this->SetColorTable (0, nNum, palette) ;
}
else // == 8 bit, 修改调色板和索引
{
for (int i=0 ; i < nNum ; i++)
palette[i].rgbBlue = FCDib::fooGetGrayscale (palette[i]) ;
// 修改索引
for (int y=0 ; y < (int)this->Height() ; y++)
{
BYTE * pLine = this->GetBits (y) ;
for (int x=0 ; x < (int)this->Width() ; x++, pLine++)
*pLine = palette[*pLine].rgbBlue ;
}
this->SetGrayPalette () ;
}
delete[] palette ;
return ;
} // >= 16 bit color
CDib OldDib (* (FCDib *) this) ; // 保存原始数据
int nSpan = OldDib.ColorBits() / 8 ;
if (this->Create (OldDib.Width(), OldDib.Height(), 8)) // gray palette setted in create
for (int y=0 ; y < (int)this->Height() ; y++)
{
BYTE * pDest = this->GetBits (y) ;
BYTE * pSrc = OldDib.GetBits (y) ;
for (int x=0 ; x < (int)this->Width() ; x++, pSrc += nSpan)
*pDest++ = FCDib::fooGetGrayscale (OldDib.ParsePixelData (OldDib.__GetPixelData (pSrc))) ;
}
}
{
BITMAPINFOHEADER * pbmfh ;
int nNum = 1 << this->ColorBits() ;
HBITMAP hBitmap ;
bool bCreate = false ; if (this->GetHandle() == NULL)
return NULL ; if (hdc == NULL)
{
hdc = ::CreateDC (TEXT("DISPLAY"), NULL, NULL, NULL) ;
bCreate = true ;
}
pbmfh = (BITMAPINFOHEADER *) new BYTE [sizeof(BITMAPV4HEADER) + ((ColorBits() <= 8) ? (nNum * 4) : 0)] ;
CopyMemory (pbmfh, &m_DibInfo, sizeof(BITMAPV4HEADER)) ;
pbmfh->biSize = sizeof(BITMAPINFOHEADER) ; // 8 位以下色设置调色板
if (this->ColorBits() <= 8)
this->GetColorTable (0, nNum, (RGBQUAD *)(pbmfh + 1)) ; hBitmap = CreateDIBitmap (hdc, (BITMAPINFOHEADER *)pbmfh, CBM_INIT,
(VOID *)m_pByte, (BITMAPINFO *)pbmfh, DIB_RGB_COLORS) ;
delete[] pbmfh ;
if (bCreate)
::DeleteDC (hdc) ;
return hBitmap ;
}
{
RGBQUAD rgb = {0, 0, 0, 0} ;
switch (this->ColorBits())
{
case 1 :
case 4 :
case 8 : this->GetColorTable ((int)dwData, &rgb) ; break ;
case 16 :
if (m_DibInfo.bV4V4Compression == BI_RGB)
rgb = fooSplit16Bit_555 ((WORD)dwData) ;
else
if (m_DibInfo.bV4GreenMask == MASK16_GREEN_555)
rgb = fooSplit16Bit_555 ((WORD)dwData) ;
else
rgb = fooSplit16Bit_565 ((WORD)dwData) ;
break ;
case 24 :
case 32 : return * (RGBQUAD *) &dwData ;
}
return rgb ;
}
//===================================================================
BOOL FCDib::SetColorTable (int iFirstIndex, int iNumber, RGBQUAD * pColors)
{
if ((this->GetHandle() == NULL) || (this->ColorBits() > 8) || (pColors == NULL))
return FALSE ;
HDC hdcMem = CreateCompatibleDC (NULL) ;
HBITMAP hBitmap = (HBITMAP) SelectObject (hdcMem, this->GetHandle()) ;
BOOL bReturn = (BOOL)::SetDIBColorTable (hdcMem, iFirstIndex, iNumber, pColors) ;
SelectObject (hdcMem, hBitmap) ;
DeleteDC (hdcMem) ;
return bReturn ;
}
不过还是感谢楼上兄弟。自己UP。