24位真彩色转换为8位灰度图片(完整代码)

2019-01-26 16:29

24位真彩色转换为8位灰度图片(完整代码)

分类: C#2011-03-04 09:29 4343人阅读 评论(5) 收藏 举报

nullfloatgdi+byte图像处理image

图像的灰度与二值化

http://www.cnblogs.com/maozefa/archive/2011/12/09/2281656.html

图像的灰度化与二值化是图像处理中最常见的处理方法,也是很多图像处理方法的基础,如图像灰度统计、图像识别等。

图像的灰度化与二值化方法较多,处理过程也比较简单。但切不可因其简单而忽视效率。如常用的图像灰度计算公式:gray = red * 0.299 + green * 0.587 + blue * 0.114,如果在程序代码中直接套用了这个公式,因浮点数的缘故导致代码执行效率较低,如改为定点整数运算,可使执行效率大大提高。 下面是图像的灰度与二值化代码: // 定义ARGB像素结构 typedef union {

ARGB Color; struct {

BYTE Blue; BYTE Green; BYTE Red; BYTE Alpha; };

}ARGBQuad, *PARGBQuad;

//---------------------------------------------------------------------------

// 图像数据data灰度化 VOID Gray(BitmapData *data)

{

PARGBQuad p = (PARGBQuad)data->Scan0;

INT offset = data->Stride - data->Width * sizeof(ARGBQuad);

for (UINT y = 0; y < data->Height; y ++, (BYTE*)p += offset) {

for (UINT x = 0; x < data->Width; x ++, p ++) p->Blue = p->Green = p->Red =

(UINT)(p->Blue * 29 + p->Green * 150 + p->Red * 77 + 128) >> 8; } }

//---------------------------------------------------------------------------

// 图像数据data灰度同时二值化,threshold阀值

VOID GrayAnd2Values(BitmapData *data, BYTE threshold) {

PARGBQuad p = (PARGBQuad)data->Scan0;

INT offset = data->Stride - data->Width * sizeof(ARGBQuad);

for (UINT y = 0; y < data->Height; y ++, (BYTE*)p += offset) {

for (UINT x = 0; x < data->Width; x ++, p ++) {

if (((p->Blue * 29 + p->Green * 150 + p->Red * 77 + 128) >> 8) < threshold) p->Color &= 0xff000000; else

p->Color |= 0x00ffffff; } } }

//---------------------------------------------------------------------------

因本文使用的是32位图像数据,所以图像的二值化没有采用通常的赋值操作p->Blue = p->Green = p->Red = 0(或者255),而是采用了位运算。

下面是使用BCB2007和GDI+图像数据实现图像灰度和二值化的例子代码: // 锁定GDI+位位图扫描线到data FORCEINLINE

VOID LockBitmap(Gdiplus::Bitmap *bmp, BitmapData *data) {

Gdiplus::Rect r(0, 0, bmp->GetWidth(), bmp->GetHeight()); bmp->LockBits(&r, ImageLockModeRead | ImageLockModeWrite, PixelFormat32bppARGB, data); }

//---------------------------------------------------------------------------

// GDI+位图扫描线解锁 FORCEINLINE

VOID UnlockBitmap(Gdiplus::Bitmap *bmp, BitmapData *data) {

bmp->UnlockBits(data); }

//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender) {

Gdiplus::Bitmap *bmp = new Gdiplus::Bitmap(L\ Gdiplus::Graphics *g = new Gdiplus::Graphics(Canvas->Handle); g->DrawImage(bmp, 0, 0); BitmapData data; LockBitmap(bmp, &data); // Gray(&data);

GrayAnd2Values(&data, 128);

UnlockBitmap(bmp, &data); g->DrawImage(bmp, data.Width, 0); delete g; delete bmp; }

//---------------------------------------------------------------------------

24位真彩色转换为8位灰度图片(完整代码)

//Code By xets007 //转载请注明出处 #include

BOOL BMP24to8(char *szSourceFile,char *szTargetFile);

int main(int argc,char* argv[]) {

//调用这个函数直接把24位真彩色灰度化

BOOL stat=BMP24to8(\ return 0; }

BOOL BMP24to8(char *szSourceFile,char *szTargetFile) {

HANDLE hSourceFile=INVALID_HANDLE_VALUE,hTargetFile=INVALID_HANDLE_VALUE; DWORD dwSourceSize=0,dwTargetSize=0; PBYTE pSource=NULL,pTarget=NULL;

hSourceFile=CreateFile(szSourceFile,GENERIC_READ,FILE_SHARE_READ,NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hSourceFile==INVALID_HANDLE_VALUE) return FALSE;

dwSourceSize=GetFileSize(hSourceFile,NULL);

pSource=(PBYTE)VirtualAlloc(NULL,dwSourceSize,MEM_COMMIT,PAGE_READWRITE); //分配空间失败或者文件太小(BMP文件不可能小于54个字节)

if(pSource==NULL||dwSourceSize<=54) {

CloseHandle(hSourceFile); return FALSE; }

DWORD dwTemp=0;

ReadFile(hSourceFile,pSource,dwSourceSize,&dwTemp,NULL);

BITMAPFILEHEADER *pSourceFileHeader=(BITMAPFILEHEADER*)pSource; BITMAPINFOHEADER

*pSourceInfoHeader=(BITMAPINFOHEADER*)(pSource+sizeof(BITMAPFILEHEADER)); //不是BMP文件或者不是24位真彩色

if(pSourceFileHeader->bfType!=0x4d42||pSourceInfoHeader->biBitCount!=24) {

CloseHandle(hSourceFile);

VirtualFree(pSource,NULL,MEM_RELEASE); return FALSE; }

CloseHandle(hSourceFile);

LONG nWidth=pSourceInfoHeader->biWidth; LONG nHeight=pSourceInfoHeader->biHeight;

LONG nSourceWidth=nWidth*3;if(nSourceWidth%4) nSourceWidth=(nSourceWidth/4+1)*4; LONG nTargetWidth=nWidth;if(nTargetWidth%4) nTargetWidth=(nTargetWidth/4+1)*4;

dwTargetSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256+nHeight*nTargetWidth;

pTarget=(PBYTE)VirtualAlloc(NULL,dwTargetSize,MEM_COMMIT,PAGE_READWRITE); memset(pTarget,0,dwTargetSize); if(pTarget==NULL) {

VirtualFree(pTarget,NULL,MEM_RELEASE); return FALSE; }

BITMAPFILEHEADER *pTargetFileHeader=(BITMAPFILEHEADER *)pTarget; BITMAPINFOHEADER *pTargetInfoHeader =

(BITMAPINFOHEADER *)(pTarget+sizeof(BITMAPFILEHEADER)); pTargetFileHeader->bfType=pSourceFileHeader->bfType; pTargetFileHeader->bfSize=dwTargetSize; pTargetFileHeader->bfReserved1=0; pTargetFileHeader->bfReserved2=0;

pTargetFileHeader->bfOffBits=sizeof(BITMAPFILEHEADER)


24位真彩色转换为8位灰度图片(完整代码).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:电与磁第一节磁现象磁场习题

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: