为什么我打开的位图文件总是掉色呢?

kencharles 2006-07-07 10:19:42
为什么我打开的图像比原图失真很多呢?还有就是我的程序运行之后,有的时候图像文件能打开,同时也就运行“AfxMessageBox("The file is opened");”这一句,而有的时候图像文件打不开,而且“AfxMessageBox("The file is opened");”这一句代码也不运行,就是不知道原因,我的图像文件都是标准的BMP图。
我的代码如下:
打开代码:
void CTBinView::OnFileOpen()
{
static char szFilter[] = "BMP Files(*.BMP)|*.BMP||";

CFileDialog FileDlg( TRUE, NULL, NULL,OFN_HIDEREADONLY, szFilter );

if( FileDlg.DoModal() == IDOK && m_Dib.Load( FileDlg.GetPathName() ) )
{
InvalidateRect( NULL, TRUE );
UpdateWindow();
AfxMessageBox("The file is opened");
}

}
其中Load的函数声明如下:
BOOL CDib::Load( const char *pszFilename )
{
CFile cf;

if( !cf.Open( pszFilename, CFile::modeRead ) )
return( FALSE );

DWORD dwDibSize;
dwDibSize =cf.GetLength() - sizeof( BITMAPFILEHEADER );

unsigned char *pDib;
pDib = new unsigned char [dwDibSize];
if( pDib == NULL )
return( FALSE );

BITMAPFILEHEADER BFH;

try{
if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
!= sizeof( BITMAPFILEHEADER ) ||BFH.bfType != 'MB' ||
cf.Read( pDib, dwDibSize ) != dwDibSize ){

delete [] pDib;
return( FALSE );
}
}

catch( CFileException *e ){
e->Delete();
delete [] pDib;
return( FALSE );
}

if( m_pDib != NULL )
delete m_pDib;

m_pDib = pDib;
m_dwDibSize = dwDibSize;

m_pBIH = (BITMAPINFOHEADER *) m_pDib;
m_pPalette =(RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)];

m_nPaletteEntries = 1 << m_pBIH->biBitCount;
if( m_pBIH->biBitCount > 8 )
m_nPaletteEntries = 0;
else if( m_pBIH->biClrUsed != 0 )
m_nPaletteEntries = m_pBIH->biClrUsed;

m_pDibBits =&m_pDib[sizeof(BITMAPINFOHEADER)+m_nPaletteEntries*sizeof(RGBQUAD)];

if( m_Palette.GetSafeHandle() != NULL )
m_Palette.DeleteObject();

if( m_nPaletteEntries != 0 ){

LOGPALETTE *pLogPal = (LOGPALETTE *) new char
[sizeof(LOGPALETTE)+
m_nPaletteEntries*sizeof(PALETTEENTRY)];

if( pLogPal != NULL ){

pLogPal->palVersion = 0x300;
pLogPal->palNumEntries = m_nPaletteEntries;

for( int i=0; i<m_nPaletteEntries; i++ ){
pLogPal->palPalEntry[i].peRed =
m_pPalette[i].rgbRed;
pLogPal->palPalEntry[i].peGreen =
m_pPalette[i].rgbGreen;
pLogPal->palPalEntry[i].peBlue =
m_pPalette[i].rgbBlue;
}

m_Palette.CreatePalette( pLogPal );
delete [] pLogPal;
}
}

return( TRUE );

}

显示图像的代码如下:
void CTBinView::OnDraw(CDC* pDC)
{
CTBinDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);

RECT Rect;
GetClientRect( &Rect );
m_Dib.SetPalette( pDC );
m_Dib.Draw( pDC, 0, 0,Rect.right, Rect.bottom );
}

其中Draw函数的声明如下:
BOOL CDib::Draw( CDC *pDC, int nX, int nY, int nWidth, int nHeight )
{

if( m_pDib == NULL )
return( FALSE );

if( nWidth == -1 )
nWidth = m_pBIH->biWidth;
if( nHeight == -1 )
nHeight = m_pBIH->biHeight;

StretchDIBits( pDC->m_hDC, nX, nY,
nWidth, nHeight,
0, 0,
m_pBIH->biWidth, m_pBIH->biHeight,
m_pDibBits,
(BITMAPINFO *) m_pBIH,
BI_RGB, SRCCOPY );

return( TRUE );

}
...全文
330 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
yzhg_cgl 2006-08-01
  • 打赏
  • 举报
回复
楼上的办法可以解决这个问题,如果LZ的显示是100%的话也不会有这种问题.
RealRaul1 2006-07-08
  • 打赏
  • 举报
回复
StretchDIBits()
之前试试
SetStretchBltMode()先
booklove 2006-07-07
  • 打赏
  • 举报
回复
这里应该没有问题
m_pBIH = (BITMAPINFOHEADER *) m_pDib;
是一整块内存。
tufaqing 2006-07-07
  • 打赏
  • 举报
回复
StretchDIBits( pDC->m_hDC, nX, nY,
nWidth, nHeight,
0, 0,
m_pBIH->biWidth, m_pBIH->biHeight,
m_pDibBits,
(BITMAPINFO *) m_pBIH, // 这个参数出问题
BI_RGB, SRCCOPY );

那个参数空间要 (BITMAPINFO *)空间 + 调色板(pLogPal->palPalEntry)空间
booklove 2006-07-07
  • 打赏
  • 举报
回复
找错误不是凭肉眼看代码,你debug一下看看Load里哪里返回的。
kencharles 2006-07-07
  • 打赏
  • 举报
回复
那问题到底出在哪里呢?
代码转载自:https://pan.quark.cn/s/11d565366452 【USB转I2C/IIC适配器上位机应用程序】是一种针对I2C(Inter-Integrated Circuit)通信协议而构建的工具,其通过USB端口将个人计算机转变为能够与I2C设备进行交互的控制器。该适配器使开发人员与工程师能够便捷地对遵循I2C协议的芯片执行读取和写入任务,因此在硬件构建和测试阶段能够显著提升效率,对于核实I2C接口芯片的工作性能具有特别的价值。 I2C协议是由飞利浦(现NXP半导体)于1980年代初创立的一种双线式串行总线,其目的是用于连接微控制器及其他外围设备。该协议仅需两条信号线(SDA - 数据线,SCL - 时钟线)即可完成多设备间的通信,大幅度削减了电路板上的布线需求,从而降低了生产成本。I2C协议提供多种速度等级,涵盖标准模式(100kbps)、快速模式(400kbps)以及高速模式(3.4Mbps),旨在满足不同场景下的应用要求。 Ginkgo USB转I2C适配器是这项技术的具体应用实例,它提供了一个物理接口,用于将USB端口转换为I2C端口。适配器内部装配有一个微控制器单元,该单元负责处理从USB到I2C的信号转换,并且通过USB线路向计算机传输信息,同时接收来自计算机的指令以操控I2C总线。这种设计使用户无需具备深厚的硬件知识,仅需借助上位机软件即可实现对I2C设备的操控。 Ginkgo I2C Adapter Classic是与该适配器相配套的软件,通常包含以下几项核心功能: 1. 设备识别:自动检测并建立与USB转I2C适配器的连接。 2. 总线探查:扫描I2C总线上所连接的设备地址,有助于准确定位设备的位置。 3. 读写指令...
代码转载自:https://pan.quark.cn/s/4c053f9292d9 在Android应用程序的设计与实现过程中,有时需要借助C或C++语言所具备的高性能特点,此时就必须借助Android Studio的NDK(Native Development Kit)工具来对C/C++代码进行编译,进而生成SO(Shared Object)动态链接库文件。本篇文章将详尽阐述在Android Studio环境下如何执行这一流程。 我们首先需要掌握Android Studio项目的基本组织架构。在Android Studio的`app`文件夹内,存在一个名为`src`的子文件夹,该文件夹通常包含了`main`以及其他相关源代码目录。在`main`文件夹中,除了我们常见的`java`文件夹外,还设立了一个`jniLibs`文件夹,此文件夹专门用于存储SO文件。除此之外,还有一个`jni`文件夹,它是用来存放C/C++源代码的地方。 为了实现C/C++代码的编写与编译,我们必须在`build.gradle`文件中配置NDK的支持。打开`app/build.gradle`文件,在`defaultConfig`部分中嵌入以下内容: ```groovy externalNativeBuild { ndkBuild { path src/main/jni/Android.mk } } ``` 这段内容明确指示Android Studio去何处寻找`Android.mk`文件,该文件是一种Makefile的变体,主要用于设定编译规则和编译目标。 接下来,我们需要创建`Android.mk`文件。在这个文件中,我们将明确指定源代码文件、编译选项以及要生成的库名称。一个基础的...
内容概要:本文围绕麦克斯韦旋度方程的差分形式在平面极化磁场中的应用展开深入研究,并通过Matlab代码实现相关数值仿真。研究的核心是将经典的麦克斯韦方程组转化为适用于数值计算的有限差分格式,构建离散化数学模型,进而模拟和分析平面极化条件下磁场的空间分布特征与时间演化规律。文中系统阐述了差分方法的理论基础与数学推导过程,详细说明网格划分、边界条件设定及迭代求解策略,最终利用Matlab编程实现电磁场的可视化仿真,有效验证了差分方法在求解复杂电磁场问题中的准确性与可行性。该研究不仅加深了对电磁波传播机理的理解,也为电磁器件的设计优化与工程仿真提供了可靠的数值分析手段。; 适合人群:具备电磁场与电磁波理论基础,熟悉偏微分方程数值解法,且掌握Matlab编程技能的电气工程、物理学、应用数学等领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①深入掌握麦克斯韦旋度方程的有限差分法基本原理及其在二维平面磁场仿真中的具体实施步骤;②学习如何利用Matlab进行电磁场问题的建模、编程求解与结果可视化;③为后续开展更复杂的电磁兼容、天线设计或光子晶体等领域的数值模拟研究奠定坚实的技术基础。; 阅读建议:建议读者结合经典电磁场理论教材,透彻理解麦克斯韦方程组的物理内涵,然后循序渐进地跟进文中的差分格式推导过程,务必动手复现并调试所提供的Matlab代码,通过调整参数观察仿真结果的变化,从而深刻领悟数值方法的实质与应用技巧。

19,464

社区成员

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

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