• 全部
  • 问答

在C/c++里面如何显示BMP文件?

nwpumtm 2001-07-19 03:27:02
有现成的函数代码最好。
...全文
48 点赞 收藏 2
写回复
2 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
leslieshen 2001-10-28
good
回复
wind_lu 2001-07-19
Within your program, you may have three different forms of a bitmap, a device-independent bitmap (DIB), a device-dependent bitmap (DDB) and a DIB section. The DIB is essentially a representation of bitmap in a manner that is independent of any device. It contains the information to enable it to be rendered on any device. There are different versions of DIBs, the most common being version 3. The specification for version 4 has also been released but this format is not yet as prevalent. There are two drawbacks to using a DIB; there are fewer functions that handle a DIB and it takes longer to render a DIB.
The device-dependent bitmap is specific to a device and it is very unlikely that a DDB for one device can be rendered on another. One such situation is when you want to render an image from the screen to a printer. In this case you would have to change the DDB to a DIB before you try to render it onto the printer. Most of the GDI functions take a DDB as an argument instead on a DIB.

The DIB section is somewhat new and designed to alleviate some of the problems with a DIB. You can use a DIB section wherever you use a DDB and yet have access to the bitmap bits and the color information. All this preamble was basically to say that you need one function to render a DIB and another to render a DDB or a DIB section.

Function 1: DrawDIB
The DrawDIB() function uses the function SetDIBitsToDevice() for to render the image. When using this function, you should be aware that the BMP file is arranged such that the first scan line (first row of pixels) is the bottom most scan line. You could actually have the top most scan line be the first if the height of the bitmap is specified as a negative value but this is rarely used. So if you want only the top half of the bitmap drawn then the nStartScan value should be half of nNumScans.
You can also use the StretchDIBits() to render the bitmap data onto a device. The StretchDIBits() function is more versatile in that it allows the bitmap to be streched or compressed and it can use various raster operations to generate the image. The StretchDIBits() function can also be used to mirror the image.

One of the argument to the DrawDIB() function is the palette that should be used when rendering the bitmap. This information can be derived from the DIB itself but using a predefined palette can help speed things up slightly.


// DrawDIB - Draws a DIB onto a device
// pDC - Pointer to a device context
// hDIB - Handle of the device-independent bitmap
// pPal - Pointer to a palette associated with the DIB
// xDest - x-coordinate of the upper-left corner of the destination rect
// yDest - y-coordinate of the upper-left corner of the destination rect
void DrawDIB( CDC* pDC, HGLOBAL hDIB, CPalette *pPal, int xDest, int yDest )
{
LPVOID lpDIBBits; // Pointer to DIB bits
BOOL bSuccess=FALSE; // Success/fail flag

BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed :
1 << bmInfo.bmiHeader.biBitCount;

// Compute the address of the bitmap bits
if( bmInfo.bmiHeader.biBitCount > 8 )
lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors +
bmInfo.bmiHeader.biClrUsed) +
((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
else
lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);

// Select and realize the palette if one supplied and if device supports it
if( pPal && (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE) )
{
pDC->SelectPalette(pPal, FALSE);
pDC->RealizePalette();
}

::SetDIBitsToDevice(pDC->m_hDC, // hDC
xDest, // DestX
yDest, // DestY
bmInfo.bmiHeader.biWidth, // nDestWidth
bmInfo.bmiHeader.biHeight, // nDestHeight
0, // SrcX
0, // SrcY
0, // nStartScan
bmInfo.bmiHeader.biHeight, // nNumScans
lpDIBBits, // lpBits
(LPBITMAPINFO)hDIB, // lpBitsInfo
DIB_RGB_COLORS); // wUsage
}

Function 2: DrawBitmap
The DrawBitmap() function can be used with both a DDB and a DIB section. This function does take into account that the destination device context might have a map mode other than MM_TEXT. This might not work always or the effect may not be what you want.

// DrawBitmap - Draws a bitmap (DDB & DIB section) onto a device
// pDC - Pointer to a device context
// hBitmap - Handle of the bitmap
// hPal - Handle of a logical palette associated with the bitmap
// xDest - x-coordinate of the upper-left corner of the destination rect
// yDest - y-coordinate of the upper-left corner of the destination rect
void DrawBitmap( CDC *pDC, HBITMAP hBitmap, HPALETTE hPal, int xDest, int yDest )
{
// Get logical coordinates
BITMAP bm;
::GetObject( hBitmap, sizeof( bm ), &bm );
CPoint size( bm.bmWidth, bm.bmHeight );
pDC->DPtoLP(&size);

CPoint org(0,0);
pDC->DPtoLP(&org);

// Create a memory DC compatible with the destination DC
CDC memDC;
memDC.CreateCompatibleDC( pDC );
memDC.SetMapMode( pDC->GetMapMode() );

//memDC.SelectObject( &bitmap );
HBITMAP hBmOld = (HBITMAP)::SelectObject( memDC.m_hDC, hBitmap );


// Select and realize the palette
if( hPal && pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
{
SelectPalette( pDC->GetSafeHdc(), hPal, FALSE );
pDC->RealizePalette();
}
pDC->BitBlt(xDest, yDest, size.x, size.y, &memDC, org.x, org.y, SRCCOPY);

::SelectObject( memDC.m_hDC, hBmOld );
}

Function 3: DrawDIBSection
Although we can use the DrawBitmap() function to draw a DIB section as well, this functions takes the color information of the bitmap into consideration and will create and use an appropriate palette when needed. Note that since this function may create a palette in each call, it might be better, for performance reasons, to create an appropriate palette from the DIB section and use the DrawBitmap() function instead. The DrawDIBSection() is handy if DIB section's color information is modified before displaying it.

// DrawDIBSection - Draws a DIB section onto a device
// hDC - Handle to a device context
// hBitmap - Handle of the DIB Section
// xDest - x-coordinate of the upper-left corner of the destination rect
// yDest - y-coordinate of the upper-left corner of the destination rect
void DrawDIBSection( HDC hDC, HBITMAP hBitmap, int xDest, int yDest )
{
HPALETTE hPal;

HDC hDCMem = ::CreateCompatibleDC( hDC );

// Create a logical palette for the bitmap
DIBSECTION ds;
BITMAPINFOHEADER &bmInfo = ds.dsBmih;
if( ::GetObject(hBitmap, sizeof(ds), &ds ) == 0 )
return; // Not a DIB Section

HGDIOBJ hBmpOld = ::SelectObject(hDCMem, hBitmap);

int nColors = bmInfo.biClrUsed ? bmInfo.biClrUsed : 1 << ds.dsBm.bmBitsPixel;

if( ::GetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE )
{
// Create a halftone palette if colors > 256.
if( nColors > 256 )
hPal = ::CreateHalftonePalette(hDC);
else
{
// Create the palette
RGBQUAD *pRGB = new RGBQUAD[nColors];

::GetDIBColorTable( hDCMem, 0, nColors, pRGB );

UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];

pLP->palVersion = 0x300;
pLP->palNumEntries = nColors;

for( int i=0; i < nColors; i++)
{
pLP->palPalEntry[i].peRed = pRGB[i].rgbRed;
pLP->palPalEntry[i].peGreen = pRGB[i].rgbGreen;
pLP->palPalEntry[i].peBlue = pRGB[i].rgbBlue;
pLP->palPalEntry[i].peFlags = 0;
}

hPal = ::CreatePalette( pLP );

delete[] pLP;
delete[] pRGB;
}

HPALETTE hPalOld = ::SelectPalette(hDC,hPal,FALSE);
::RealizePalette(hDC);
BitBlt(hDC,xDest,yDest,bmInfo.biWidth,bmInfo.biHeight,hDCMem,0,0,SRCCOPY);

::SelectPalette(hDC,hPalOld,FALSE);
// delete GDI objects
::DeleteObject(hPal);
}
else
BitBlt(hDC,xDest,yDest,bmInfo.biWidth,bmInfo.biHeight,hDCMem,0,0,SRCCOPY);

::SelectObject(hDCMem, hBmpOld);
::DeleteDC(hDCMem);

回复
相关推荐
[C/C++]读写BMP文件
BMP格式详细资料请参考:[Baidu]链接 [Wiki]链接 [博客]链接需要包含的头文件#include &lt;Windows.h&gt; #include &lt;stdio.h&gt;1. 读8位BMP(灰度图).BYTE* Read8BMP( int &amp;nWidth, ...
BMP文件学习笔记(一): C/C++语言实现.bmp文件读写
1 认识BMP文件 bmp文件结构: 第一部分:位图文件头BITMAPFILEHEADER,是一个结构。这个结构的长度是固定的,为14个字节(WORD为无符号16位整数,DWORD为无符号32位整数)。 其定义如下: typedef struct ...
bmp.rar_图片显示_C/C++_源码
读取BMP文件,返回图片长宽和灰度像素值
图像到 C/C++ 数组转换器:此程序将 BMP/TIFF/JPG/PNG 文件转换为单色图像和嵌入的 C/C++ 字节数组。...
该程序将 BMP/TIFF/JPG/PNG 文件转换为嵌入的 C/C++ 字节数组。 当您想显示器上显示单色图像时,这非常有用。 它数据数组生成之前将您的图像转换为单色。 源图像中较暗的颜色将产生“开”像素,而较亮的颜色将...
多媒体技术 实验作业3 BMP位图文件的解析.zip
包含实验要求和可执行文件。...编写C/C++程序,读取一个24位真彩色BMP文件,然后转化为灰色图像,最后存储为8位伪彩色BMP文件。 编写C/C++程序,读取一个8位伪彩色BMP文件,转化为24位真彩色BMP文件,最后存储。
C/C++图像处理编程.陆宗骐(带详细书签).pdf
本书既介绍原理又给出实现的C语言C++程序,程序实例VC下编译、调试,并Windows环境下运行。 本书第1~4章介绍图像显示与存储的基础知识及其编程。第5~9章介绍图像处理的常用算法及其编程。第10~12章介绍Windows...
C语言/C++BMP图片加椒盐噪声 超简单
#include <fstream> #include <math.h> #include <stdio.h> #include <windows.h> #include <iostream> using namespace std; //引入时间库 和 随机函数库 ...#include<...
读取BMP文件显示出来(C++实现)
读取BMP文件的时候我们首先需要弄清楚bmp格式文件的结构 bmp的文件格式 bmp文件包含windows.h的头文件里。编写代码的时候可以直接调用Windows.h 头文件来调用。
BMP图像文件读写操作类,C++实现,支持24位位图
BMP图像文件读写操作类,C++实现,支持24位位图。适合学习用。
ReadBMP.zip_图形图像处理_C/C++_源码
利用C语言读取.BMP图像的文件信息及图像信息,该程序以LENA图为例。
24位BMP文件读取、BMP文件转灰度图(附c/c++代码+详细注释)
1.BMP文件的格式介绍 BMP图像文件由四部分组成: 位图文件头数据结构,它包含BMP图像文件的类型、显示内容等信息; 位图信息头数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息; 调色板,这个...
C++ /文件流 /BMP文件读写
C++文件C++ 通过以下几个类支持文件的输入输出: ofstream: 写操作(输出)的文件类 (由ostream引申而来)ifstream: 读操作(输入)的文件类(由istream引申而来)fstream: 可同时读写操作的文件类 (由...
c#+毕业设计+源码-stb:用于C/C++的stb单文件公共域库
文件/内存中加载/解码图像:JPG,PNG,TGA,BMP,PSD,GIF,HDR,PIC 1.24 图形 5011 解析,解码和光栅化TrueType字体中的字符 1.15 图形 1690 图像写入磁盘:PNG,TGA,BMP 0.96 图形 2631 以良好的质量调整图像...
C语言读写24BMP文件,32位BMP转24位BMP
C语言读写24BMP文件,32位BMP转24位BMP; 详情参见:https://blog.csdn.net/libizhide/article/details/104144513 下载后请修改错误:main.c中55行pic=(PIC *)malloc(1);改为pic=(PIC *)malloc(sizeof(PIC)*1);
(原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
Abstract若要做影像處理,第一件事情就是要能將圖片讀進來變成array,才能套用各種演算法,之前我的作法是用.NET的GDI+,方便雖方便,但缺點就是被綁死.NET平台,如作SW/HW CoD
MFC动态加载/清除显示JPG/BMP/ICO图片文件
MFC 动态加载图片,支持jpg\bmp\ico\等格式,只要修改一下,所有的格式都支持, 支持清除图片显示
C++语言写bmp文件的程序完整版
#include #include /* 定义WORD为两个字节的类型 */ typedef unsigned short WORD;.../* 位图文件头主要是对位图文件的一些描述 位图信息头主要是对位图图像方面信息的描述 */ /*************************** 位图
C语言C++BMP图像的缩放
#include <fstream> #include <math.h> #include <stdio.h> #include <windows.h> #include <iostream> using namespace std; int main() ... unsigned int Height =...
c语言读取bmp文件
c语言读取bmp文件、vs2010工程
c语言BMP文件加水印
c语言BMP文件加水印,可使用devc++打开,使用c语言BMP文件加水印
C/C++信息隐写术(三)之txt文件藏入BMP文件
C/C++信息隐写术(三)之txt文件藏入BMP文件
C/C++语言图像处理:各种滤波
C语言图像处理:各种滤波 对于新手学习图像处理有较好的参考价值。 解压后将.bmp和.c文件放在同一文件夹下即可直接运行即可 (macos系统使用Xcode需要把文件路径改成绝对路径)
ssceenshoot:desktop_computer:的工具-C/C++开发
屏幕截图配置文件ssceenshoot的工具首先,这是一个轮子。 该软件以Microsoft系统的屏幕快照为模型。 该程序用C语言编写,并使用win32 API。...保存bmp文件功能。 待办事项列表:屏幕截图中,Spectroscop
C/C++语言图像处理:条形码识别
C语言图像处理:条形码识别 对于新手学习图像处理有较好的参考价值。 解压后将.bmp和.c文件放在同一文件夹下即可直接运行即可 (macos系统使用Xcode需要把文件路径改成绝对路径)
C/C++编程:C生成BMP、PNG和JPEG图片:
学习图形图像的过程中,最简单和常见的格式是BMP和PPM。下面将给出生成BMP的极度精简代码,然后讲解BMP格式。 #include <stdio.h> #include <stdlib.h> #define w 200 #define h 200 void WriteBMP...
bmp2cpp:将bmp文件转换为C++文件中数据数组的简单工具-源码
BMP2CPP 工具读取 BMP 文件并生成带有像素数组的 C++ 文件。 它可用于 C++ 中快速包含二进制文件作为源文件。 用法 ./bmp2cpp <bmp> [-o ] 汇编 $ make
gaussblur.zip_图形图像处理_C/C++_源码
双边滤波、高斯模糊的C++实现,不依靠任何库,读取bmp图像文件
C/C++实现RGB565转BMP图像
分为两个文件 rgb2bmp.h 和 rgb2bmp.c 需要注意的BMP格式文件的头部的14个字节和40个字节的结构体 rgb2bmp.h //rgb2bmp.h文件 #include &lt;stdio.h&gt; typedef unsigned char BYTE; typedef unsigned ...
《UML面向对象需求分析与建模教程》 邹盛荣 主编 电子版 2016.01 .doc
PPT已在CSDN均可免费下载 《UML面向对象需求分析与建模教程》 邹盛荣 主编 电子版 2016.01 .doc 当当网上可购买纸质书: http://product.dangdang.com/23766413.html
STM32F407 / F103 PCF8575模块 控制16个I/O口 IIC通信
本例程为STM32F407控制PCF8575模块的16个I/O口输出,本例程基于正点原子STM32F407 IIC例程修改,本例程中使用PCF8575控制16个继电器。
发帖
游戏开发
创建于2007-08-27

7920

社区成员

游戏开发相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2001-07-19 03:27
社区公告
暂无公告