请问:怎么把24位真彩色位图转成灰度图?

toneyxw 2004-03-31 03:19:59

24位真彩色位图没有调色板而且每个象素都是三个字节表示的,

转成灰度图是不是要创建新的调色板,并且把每个象素用一个字节表示?

vc下一直没有实现,郁闷的很,请大虾们帮帮忙
...全文
476 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tomcat4 2004-06-11
  • 打赏
  • 举报
回复
收藏!
酒红绿叶 2004-06-09
  • 打赏
  • 举报
回复
还是不行的话给我留言,,我有正确的程序!
代码医生 2004-06-09
  • 打赏
  • 举报
回复
// bitmap2View.h : interface of the CBitmap2View class
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_BITMAP2VIEW_H__8F807D3D_0DB1_4FDC_A94F_C00079FA1838__INCLUDED_)
#define AFX_BITMAP2VIEW_H__8F807D3D_0DB1_4FDC_A94F_C00079FA1838__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


class CBitmap2View : public CView
{
protected: // create from serialization only
CBitmap2View();
DECLARE_DYNCREATE(CBitmap2View)

// Attributes
public:
CBitmap2Doc* GetDocument();
CString str;
LPBYTE pData;
BITMAPINFOHEADER bmih;//BMP文件信息变量
DWORD BytesPerLine;
DWORD dwLen;
BOOL tu;
// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CBitmap2View)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CBitmap2View();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
//{{AFX_MSG(CBitmap2View)
afx_msg void OnFileOpen();
afx_msg void OnCover();
afx_msg void OnUpdateCover(CCmdUI* pCmdUI);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

#ifndef _DEBUG // debug version in bitmap2View.cpp
inline CBitmap2Doc* CBitmap2View::GetDocument()
{ return (CBitmap2Doc*)m_pDocument; }
#endif

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_BITMAP2VIEW_H__8F807D3D_0DB1_4FDC_A94F_C00079FA1838__INCLUDED_)
代码医生 2004-06-09
  • 打赏
  • 举报
回复
我找到的一段代码,我试过了,好用,呵呵
// bitmap2View.cpp : implementation of the CBitmap2View class
//

#include "stdafx.h"
#include "bitmap2.h"

#include "bitmap2Doc.h"
#include "bitmap2View.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CBitmap2View

IMPLEMENT_DYNCREATE(CBitmap2View, CView)

BEGIN_MESSAGE_MAP(CBitmap2View, CView)
//{{AFX_MSG_MAP(CBitmap2View)
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
ON_COMMAND(IDC_COVER, OnCover)
ON_UPDATE_COMMAND_UI(IDC_COVER, OnUpdateCover)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBitmap2View construction/destruction

CBitmap2View::CBitmap2View()
{
// TODO: add construction code here
str = "";
tu = FALSE;
}

CBitmap2View::~CBitmap2View()
{
delete [] pData;

}

BOOL CBitmap2View::PreCreateWindow(CREATESTRUCT& cs)
{
return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CBitmap2View drawing

void CBitmap2View::OnDraw(CDC* pDC)
{
CBitmap2Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);

if( str != "" )
{
CWnd *m_pMainWnd;
m_pMainWnd = AfxGetMainWnd();
m_pMainWnd->SetWindowText("显示图片");//改变窗口标题

RGBTRIPLE *rgb;//24位真彩色数据格式
rgb = new RGBTRIPLE[dwLen];

BYTE *pLine = NULL;
BYTE *pDesLine = NULL;
for(int q = 0;q < bmih.biHeight;++q) //copy one scanline
{
pLine = &pData[q * BytesPerLine];
pDesLine = &((BYTE *)rgb)[q * bmih.biWidth * 3];//?强制转换需乘3?
memcpy(pDesLine,pLine,bmih.biWidth * 3);
}
for (int i=0; i<bmih.biHeight;i++)
{
for (int j=0; j<bmih.biWidth; j++)
{
pDC->SetPixel(j,bmih.biHeight-i,RGB(rgb[i*bmih.biWidth+j].rgbtRed,rgb[i*bmih.biWidth+j].rgbtGreen,rgb[i*bmih.biWidth+j].rgbtBlue));
}
}
delete rgb;//释放内存
pDC->TextOut(0,0,str);
ReleaseDC(pDC);
}
}

/////////////////////////////////////////////////////////////////////////////
// CBitmap2View printing

BOOL CBitmap2View::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}

void CBitmap2View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}

void CBitmap2View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CBitmap2View diagnostics

#ifdef _DEBUG
void CBitmap2View::AssertValid() const
{
CView::AssertValid();
}

void CBitmap2View::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}

CBitmap2Doc* CBitmap2View::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CBitmap2Doc)));
return (CBitmap2Doc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CBitmap2View message handlers

void CBitmap2View::OnFileOpen()
{
CString sFilter="DIB Files(* .bmp)|* .bmp|All Files(* .*)|* .*||";

CFileDialog Dlg( TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
(LPCTSTR)sFilter,NULL );
Dlg.DoModal();
CString sstr;
sstr = Dlg.GetPathName();

if(sstr!="")
{
tu = TRUE;
CFile cf;
CFileException e;//出错处理
BITMAPFILEHEADER bmfh;//BMP文件头变量
LPBITMAPINFOHEADER m_lpBMPHdr;
int size;

if ( !cf.Open((LPCTSTR)sstr,CFile::modeRead, &e) )
{
MessageBox( "Can not open the file!","24Open File" );
return;
}
cf.Read( (LPVOID) &bmfh, sizeof( BITMAPFILEHEADER ) );
if ( bmfh.bfType != 0x4d42 )
{
AfxMessageBox("不是位图");
}
else
{
size = bmfh.bfOffBits - sizeof( BITMAPFILEHEADER );
m_lpBMPHdr = ( LPBITMAPINFOHEADER ) new char[size];
cf.Read( m_lpBMPHdr, size );
if( m_lpBMPHdr->biBitCount !=24 )
{
AfxMessageBox("这不是24位图");
}
else
{
bmih= *m_lpBMPHdr;
BytesPerLine = bmih.biWidth * 3;//计算Bmp扫描行字节数
if( BytesPerLine % 4 != 0 )
BytesPerLine = (BytesPerLine / 4 + 1) * 4;//四字节对齐;
dwLen = BytesPerLine * bmih.biHeight;

pData = new BYTE[dwLen];
cf.Read( pData, dwLen );
str = "24位真彩色图!";
this->Invalidate();//发WM_POINT重调ondraw()
}
delete [] m_lpBMPHdr;
}
cf.Close();//关闭文件

}
}

void CBitmap2View::OnCover()
{
// TODO: Add your command handler code here
if( str != "" )
{
tu = FALSE;
LPBYTE lpTemp = pData;
BYTE gray;
DWORD i = 0;
DWORD count = bmih.biWidth * bmih.biHeight;
while( i < count )
{
gray = ( lpTemp[0] + lpTemp[1] + lpTemp[2] )/3;
*lpTemp++ = gray;
*lpTemp++ = gray;
*lpTemp++ = gray;
i++;
}
str = "24位真彩色图变灰!";
this->Invalidate(FALSE);//发WM_POINT重调ondraw()
}
}

void CBitmap2View::OnUpdateCover(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(tu);
}
wrcluomo 2004-04-01
  • 打赏
  • 举报
回复
这个你找以前的贴子,N多次了.不用再问了.
酒红绿叶 2004-04-01
  • 打赏
  • 举报
回复
我没有转的源程序,要是有时间可以帮你做一个,

不过实在是忙!!

道理基本上相同阿,,

重新构建一副bmp,申请连续内存,计算好内存大小!

fileheader + infoheader + rgbquad + bits

你需要新建一个rgbquad,
bits需要根据24位的转换,公式到处都有,

然后,没什么了!!


fyhfyh1231 2004-03-31
  • 打赏
  • 举报
回复
转灰度图只要将其图素的RGB的值变成原RGB和的平均值就行了.得到它的图素地址,将其值改掉再保存就行了.
toneyxw 2004-03-31
  • 打赏
  • 举报
回复
我用alfwolf(戈壁孤狼) 的代码有问题,转换之后无法保存图像,也就是24位真彩色源图像

转成的灰度图已经不是位图了。

puhuofeie(扑火飞蛾) ,你给的链接程序我也下载过,不过,我不想用DLL,想自己编程实现

还是没头绪啊:(
酒红绿叶 2004-03-31
  • 打赏
  • 举报
回复
程序!
http://www.vckbase.com/code/listcode.asp?mclsid=7&sclsid=703
酒红绿叶 2004-03-31
  • 打赏
  • 举报
回复
: alfwolf(戈壁孤狼) 说得已经很好了!
toneyxw 2004-03-31
  • 打赏
  • 举报
回复
请问这个BmpLength变量是什么?整个BMP文件长度?
alfwolf 2004-03-31
  • 打赏
  • 举报
回复
sorry,顺序是G B R
alfwolf 2004-03-31
  • 打赏
  • 举报
回复
我写的函数
灰度图的调色板很简单,从0-255
注意24位位图颜色顺序为B G R
//构造灰度位图文件
HANDLE CGDICapture::MakeGrayScaleBmpFile(HANDLE pColorBmp)
{
if(pColorBmp == NULL)
{
return pColorBmp;
}
if(nColors > 0)
{
char *read = (char*)pColorBmp + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
char *write = (char*)pColorBmp + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
int r,g,b;
float Y;
BYTE gray;
for(int i=0;i<nColors;i++)
{
g = (unsigned char)*read++;
b = (unsigned char)*read++;
r = (unsigned char)*read++;
read++;
//提取灰度分量
Y=(float)(r*0.299+g*0.587+b*0.114);
gray = (BYTE)Y;
*write = gray;
write++;
*write = gray;
write++;
*write = gray;
write++;
*write = gray;
write++;
}
}
else
{
//将RGB模式的位图转换为256色灰度位图
char *pgray = new char[BmpLength];
char *read = (char*)pColorBmp + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
char *write = pgray;

//构造调色板信息
for(int i=0;i<256;i++)
{
*(write+i*4) = i;
*(write+i*4+1) = i;
*(write+i*4+2) = i;
*(write+i*4+3) = 0;
}
write += sizeof(RGBQUAD)*256;

int r,g,b;
float Y;
BYTE gray;
for(int h=0;h<nDisplayHeight;h++)
{
for(int w=0;w<nDisplayWidth;w++)
{
g = (unsigned char)*read++;
b = (unsigned char)*read++;
r = (unsigned char)*read++;
//提取灰度分量
Y=(float)(r*0.299+g*0.587+b*0.114);
gray = (BYTE)Y;
*write = gray;
write++;
}
}

//拷贝新的灰度位图调色板信息和像素数据
memcpy((char*)pColorBmp + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER),
pgray,
nDisplayWidth*nDisplayHeight + sizeof(RGBQUAD)*256);

//设置位图文件头
BITMAPFILEHEADER bmfHdr;
bmfHdr.bfType = 0x4D42; // "BM"
BmpLength = bmfHdr.bfSize = nDisplayWidth*nDisplayHeight + sizeof(RGBQUAD)*256 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)
+ (DWORD)sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256;
memcpy((BYTE*)pColorBmp, &bmfHdr, sizeof(BITMAPFILEHEADER));

//设置位图信息头
BITMAPINFOHEADER bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = nDisplayWidth;
bi.biHeight = nDisplayHeight;
bi.biPlanes = 1;
bi.biBitCount = 8;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
memcpy((BYTE*)pColorBmp + sizeof(BITMAPFILEHEADER), &bi, sizeof(BITMAPINFOHEADER));

//拷贝新的灰度位图调色板信息和像素数据
memcpy((char*)pColorBmp + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER), pgray, nDisplayWidth*nDisplayHeight + sizeof(RGBQUAD)*256);
//释放分配的临时空间
delete pgray;
}
return pColorBmp;
}

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧