vc++编程实现显示灰度直方图的详细步骤
图像灰度化方法总结及其VC实现

图像灰度化方法总结及其VC实现最近一段时间作者开始进行运动目标识别定位系统设计,本文以及后续的几篇文章都是从一个图像处理初学者的角度来总结目标检测定位过程中所应用到的各种常见的算法,尤其是解决算法实现过程中由于粗心大意或者C编程基本功不扎实所引起的各种问题。
本文主要对彩色图片灰度化的方法及其实现过程进行总结,最终给出实现的C代码。
在进行视频流目标识别与跟踪时,通常第一个步骤就是对采集到的彩色图像进行灰度化,这是因为黑白照片数据量小,相比彩照更易实现实时算法,另一方面黑白照片是由未处理的光线所形成的照片,因此从图像处理学角度来看,这种未经特殊滤光处理的图片所涵盖的信息更有价值。
目前,在图像处理过程中,最常用的彩色图片格式有RGB,HSV、YUV以及HLS三种。
以下分别对这三种格式的彩色图像进行灰度化实现。
1、RGB空间图像定义于RGB空间的彩色图,其每个像素点的色彩由R、G、B三个分量共同决定。
每个分量在内存所占的位数共同决定了图像深度,即每个像素点所占的字节数。
以常见的24深度彩色RGB图来说,其三个分量各占1个字节,这样每个分量可以取值为0~255,这样一个像素点可以有1600多万(255*255*255)的颜色的变化范围。
对这样一幅彩色图来说,其对应的灰度图则是只有8位的图像深度(可认为它是RGB三个分量相等),这也说明了灰度图图像处理所需的计算量确实要少。
不过需要注意的是,虽然丢失了一些颜色等级,但是从整幅图像的整体和局部的色彩以及亮度等级分布特征来看,灰度图描述与彩色图的描述是一致的。
对于RGB图像进行灰度化,通俗点说就是对图像的RGB三个分量进行加权平均得到最终的灰度值。
最常见的加权方法如下:1)Gray=B;Gray=G;Gray=R2)Gray=max(B+G+R)3)Gray=(B+G+R)/34)Gray= 0.072169B+ 0.715160G+ 0.212671R5)Gray= 0.11B+ 0.59G+ 0.3R这三种方法中,第一种为分量法,即用RGB三个分量的某一个分量作为该点的灰度值;第二种方法为最大值法,将彩色图像中的三分量亮度的最大值作为灰度图的灰度值。
cvtcolor 函数 原理 c++ opencv 背后代码

cvtColor是OpenCV 中的一个非常有用的函数,用于将图像从一种颜色空间转换到另一种颜色空间。
在C++ 中,它的基本语法如下:
cpp复制代码
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0);
其中:
•src是输入图像,它是一个多通道的图像。
•dst是输出图像,它的类型和通道数由code参数决定。
•code是转换类型,比如CV_BGR2GRAY,CV_BGR2HSV等。
•dstCn是输出图像的通道数,如果为0,则根据code参数确定通道数。
下面我们深入到其背后代码的工作原理:
cvtColor的工作方式是通过使用查找表(LUT)来实现的。
查找表是一个预先计算好的数组,用于快速查找像素的转换值。
这使得颜色空间转换可以在常数时间内完成,大大提高了效率。
对于每个像素,我们可以通过查找表找到其在新颜色空间中的值。
例如,如果我们正在将一个RGB 图像转换为灰度图像,那么对于每个RGB 值,我们可以在查找表中查找其对应的灰度值。
然后,我们用这个灰度值替换原来的RGB 值。
这种方法的优点是速度快,但也有一个缺点:它需要预先计算查找表,这可能会占用大量的内存。
然而,对于大多数应用来说,这是可以接受的。
请注意,OpenCV 提供了许多内置的颜色空间转换代码,如CV_BGR2GRAY(从BGR 颜色空间到灰度颜色空间),CV_BGR2HSV(从BGR 颜色空间到HSV 颜色空间)等。
用户也可以定义自己的颜色空间转换代码。
VC++编程实现对曝光不足照片的修复(直方图均衡化)

VC++编程实现对曝光不足照片的修复引言一般来说,照相产生缺陷的原因主要有对焦不准、光圈选择不合适以及暴光不足等几种情况,前两种情况的偶然性较强,而曝光不足虽也具有一定的偶然性但对于某些特殊情况比如暗中侦察等不方便使用闪光灯的场合则较为普遍。
因此,有必要对曝光不足的照片提出一种比较通用的照片修复处理方法。
修复方法的设计根据照相的一般原理:物体反射的光线经过透镜投影到胶片上,胶片上的感光颗粒根据光线的强弱做出不同程度的分解从而显现出不同的颜色。
当没有使用闪光灯或暴光时间过短而造成照片曝光不足时,照射在胶片上的光线强度不够或照射时间过短均会使感光颗粒分解不完全,冲洗出来的照片就会发暗,下图便是一幅实际的曝光不足照片,可以看出整幅照片很昏暗,除了位于左下的三、四个大字隐约可见外,几乎看不出该照片到底拍了些什么。
虽然感光颗粒由于曝光不足而使照片显地昏暗,但由于同一胶片上的感光颗粒的感光程度仍是同真实物体所反射光线成比例的,因此在胶片上实际仍保存了真实物体的大部分信息,只是由于曝光不足造成的分解不完全使冲洗出的照片灰度分布过于集中,并超出了人眼对灰度级的分辨程度,才造成了视觉上的不可见。
通过程序对照片做灰度分布统计(如下图所示)也可以看出照片的灰度分布主要集中在0 ~ 100之内,这显然是很暗的了。
基于以上几点认识,在进行照片修复时只要将过于集中的灰度分布按照一定的规则将其均匀分布于整个灰度区间即可在视觉上得到相当程度的改善。
在这方面的处理方法中,灰度均衡化和灰度规定化(含单映射和组映射两种规则)应用较为广泛,但后者需要根据图象的不同人为规定好适当的预期灰度分布规则才能得到满意的效果,如果预期灰度分布规定不当则处理效果会很差,因此后者的通用性不好。
而前者在处理时则只需要将当前的灰度分布均衡的分布于整个灰度区间即可,虽然对于某一幅特定的图象处理效果可能不及灰度规定化,但通用性却要好的多,对任意的图象均可获得相当不错的处理效果。
C语言控制台图形化编程

C语言控制台图形化编程在计算机编程领域,图形化界面一直是提高用户体验的重要手段之一。
在C语言中,虽然没有直接支持图形化编程的库函数,但我们可以利用一些技巧和库来实现控制台图形化编程。
本文将介绍如何在C语言中通过控制台绘制基本的图形和实现简单的交互效果。
一、基本概念在开始编写控制台图形化程序之前,我们需要了解一些基本概念。
首先是像素和字符的概念,控制台上的每个字符都可以看作一个像素,可以通过改变字符的颜色来实现绘图效果。
其次是控制台的坐标系,通常以左上角为原点,向右为X轴正方向,向下为Y轴正方向。
二、绘制基本图形1. 绘制点在控制台中绘制点可以通过改变字符的颜色实现,可以使用Windows API函数SetConsoleTextAttribute来设置字符的颜色。
例如,下面代码可以绘制一个红色的点:```c#include <windows.h>#include <stdio.h>void gotoxy(int x, int y) {COORD pos;pos.X = x;pos.Y = y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);}void setcolor(int color) {HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleTextAttribute(hConsole, color);}int main() {int x = 10, y = 5;gotoxy(x, y);setcolor(FOREGROUND_RED);printf("*");return 0;}```2. 绘制线段要在控制台中实现绘制线段的效果,我们可以利用字符的重复打印来模拟直线的效果。
例如,下面代码可以绘制一条水平线段:```c#include <stdio.h>void setcolor(int color) {printf("\033[1;%dm", color);}int main() {int x1 = 10, x2 = 20, y = 5;setcolor(31); // 设置为红色for (int i = x1; i <= x2; i++) {printf("*");}return 0;}```3. 绘制矩形要在控制台中绘制矩形,可以利用循环来控制每行的输出。
C语言实现图像识别

C语言实现图像识别图像识别是计算机视觉领域的重要研究方向之一,它通过算法和模型实现计算机对图像内容的理解和分类。
C语言是一种通用的高级编程语言,具有高效性和强大的计算能力,因此在图像识别领域中也有广泛的应用。
本文将介绍C语言在图像识别方面的应用和实现。
一、图像预处理在进行图像识别之前,首先需要对图像进行预处理。
图像预处理的目的是去除图像中的噪声、调整图像的对比度和亮度等,从而更好地提取图像特征。
在C语言中,我们可以使用各种图像处理库,如OpenCV来实现图像预处理。
下面是一个简单的C语言代码示例,演示了如何使用OpenCV对图像进行预处理:```C#include <opencv2/opencv.hpp>using namespace cv;int main(){// 读取图像Mat image = imread("image.jpg", IMREAD_COLOR);// 转为灰度图像cvtColor(image, image, COLOR_BGR2GRAY);// 高斯模糊GaussianBlur(image, image, Size(5, 5), 0);// 边缘检测Canny(image, image, 50, 150);// 显示图像imshow("Processed Image", image);waitKey(0);return 0;}```二、特征提取在进行图像识别之前,还需要提取图像的特征。
特征提取是将图像转换为计算机可理解的数值形式,以便进行进一步的处理和分类。
C 语言提供了各种特征提取的方法和算法的实现,下面是一个简单的C 语言代码示例,演示了如何使用C语言进行图像特征提取:```C#include <stdio.h>int main(){// 读取图像特征数据float features[100];FILE *file = fopen("features.txt", "r");for (int i = 0; i < 100; i++) {fscanf(file, "%f", &features[i]);}fclose(file);// 进行图像分类或其他处理// ...return 0;}```三、模型训练与识别在进行图像识别之前,需要训练一个模型来对图像进行分类。
C语言数字图像处理之直方图均衡化

C语⾔数字图像处理之直⽅图均衡化本⽂实例为⼤家分享了C语⾔直⽅图均衡化的具体代码,供⼤家参考,具体内容如下原理直⽅图均衡化(Histogram Equalization) ⼜称直⽅图平坦化,实质上是对图像进⾏⾮线性拉伸,重新分配图像象元值,使⼀定灰度范围内象元值的数量⼤致相等。
这样,原来直⽅图中间的峰顶部分对⽐度得到增强,⽽两侧的⾕底部分对⽐度降低,输出图像的直⽅图是⼀个较平的分段直⽅图:如果输出数据分段值较⼩的话,会产⽣粗略分类的视觉效果。
直⽅图是表⽰数字图像中每⼀灰度出现频率的统计关系。
直⽅图能给出图像灰度范围、每个灰度的频度和灰度的分布、整幅图像的平均明暗和对⽐度等概貌性描述。
灰度直⽅图是灰度级的函数, 反映的是图像中具有该灰度级像素的个数, 其横坐标是灰度级r, 纵坐标是该灰度级出现的频率( 即像素的个数) pr( r) , 整个坐标系描述的是图像灰度级的分布情况, 由此可以看出图像的灰度分布特性, 即若⼤部分像素集中在低灰度区域, 图像呈现暗的特性; 若像素集中在⾼灰度区域, 图像呈现亮的特性。
灰度数字图像是每个像素只有⼀个采样颜⾊的图像。
这类图像通常显⽰为从最暗⿊⾊到最亮的⽩⾊的灰度。
灰度图像与⿊⽩图像不同,在计算机图像领域中⿊⽩图像只有⿊⽩实现流程:1)统计每个灰度级像素点的个数2)计算灰度分布密度3)计算累计直⽅图分布4)累计分布取整,保存计算出来的灰度映射关系处理图⽚规格800*600 8位灰度单通道原图直⽅图均衡化分析:本次实验中,我故意把原图调暗,进⾏直⽅图均衡化后可以明显感受到整幅图像亮度增⼤了,⽽且某些细节⽅⾯更加突出。
出现问题最初进⾏直⽅图均衡化时,输出结果如下:经分析,是没有对数组初始化置零导致的。
Hist数组是进⾏⼀个统计像素点个数的数组,最初倘若不置零,结果必然毫⽆意义。
故⽽添加数组内存置零的操作:经测试,问题解决。
附代码#include <stdio.h>#include <stdlib.h>#include <memory.h>#define height 600#define width 800typedef unsigned char BYTE; // 定义BYTE类型,占1个字节int main(void){FILE *fp = NULL;//BYTE Pic[height][width];BYTE *ptr;BYTE **Pic = new BYTE *[height];for (int i = 0; i != height; ++i){Pic[i] = new BYTE[width];}fp = fopen("weiminglake_huidu.raw", "rb");ptr = (BYTE*)malloc(width * height * sizeof(BYTE));//创建内存for (int i = 0; i < height; i++){for (int j = 0; j < width; j++){fread(ptr, 1, 1, fp);Pic[i][j] = *ptr; // 把图像输⼊到2维数组中,变成矩阵型式ptr++;}}fclose(fp);int hist[256];float fpHist[256];float eqHistTemp[256];int eqHist[256];int size = height *width;int i, j;memset(&hist, 0x00, sizeof(int) * 256);memset(&fpHist, 0x00, sizeof(float) * 256);memset(&eqHistTemp, 0x00, sizeof(float) * 256);for (i = 0; i < height; i++) //计算差分矩阵直⽅图直⽅图统计每个灰度级像素点的个数{for (j = 0; j < width; j++){unsigned char GrayIndex = Pic[i][j];hist[GrayIndex] ++;}}for (i = 0; i< 256; i++) // 计算灰度分布密度{fpHist[i] = (float)hist[i] / (float)size;}for (i = 0; i< 256; i++) // 计算累计直⽅图分布{if (i == 0){eqHistTemp[i] = fpHist[i];}else{eqHistTemp[i] = eqHistTemp[i - 1] + fpHist[i];}}//累计分布取整,保存计算出来的灰度映射关系for (i = 0; i< 256; i++){eqHist[i] = (int)(255.0 * eqHistTemp[i] + 0.5);}for (i = 0; i < height; i++) //进⾏灰度映射均衡化{for (j = 0; j < width; j++){unsigned char GrayIndex = Pic[i][j];Pic[i][j] = eqHist[GrayIndex];}}fp = fopen("output.raw", "wb");for (i = 0; i < height; i++){for (j = 0; j < width; j++){fwrite(&Pic[i][j], 1, 1, fp);}}fclose(fp);return 0;}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
C#两种获取灰度图像的方法

C#两种获取灰度图像的方法第一种:在图像处理程序开发中,常会遇到将一幅彩色图像转换成灰度图像的情况,笔者在最近的一个项目中便遇到了这点。
经过一翻努力最终解决,想想有必要分享一下,于是便写下此文。
在本文中,将向各位读者介绍两种实现这一变换的方法,这也是笔者先后使用的两种方法。
本文的例子使用C#语言编写,使用的集成开发环境是Visual Studio 2005。
第一种,直接调用GetPixel/SetPixel方法。
我们都知道,图像在计算机中的存在形式是位图,也即一个矩形点阵,每一个点被称为一个像素。
在这种方法中,我们通过GDI+中提供的GetPixel方法来读取像素的颜色,并加以计算,然后再使用SetPixel方法将计算后的颜色值应用到相应的像素上去,这样便可以得到灰度图像。
上边提到的“计算”便是指得到灰度图像的计算,其公式是:r = (像素点的红色分量 + 像素点的绿色分量 + 像素点的蓝色分量) / 3最后得到的r便是需要应用到原像素点的值。
具体的编程实现也非常的简单,只需要遍历位图的每一个像素点,然后使用SetPixel方法将上边计算得到的值应用回去即可。
主要代码如下所示:Color currentColor;int r;Bitmap currentBitmap = new Bitmap(picBox.Image);Graphics g = Graphics.FromImage(currentBitmap);for (int w = 0; w < currentBitmap.Width; w++){for (int h = 0; h < currentBitmap.Height; h++){currentColor = currentBitmap.GetPixel(w, h);r = (currentColor.R + currentColor.G + currentColor.B) / 3;currentBitmap.SetPixel(w, h, Color.FromArgb(r, r, r));}}g.DrawImage(currentBitmap, 0, 0);picBox.Image = currentBitmap;g.Dispose();以上代码非常简单,不需要做太多的解释。
自行编写代码计算灰度图像的直方图

数字图像处理实验报告姓名:___王程___学号:_2012021199037_日期:_2013.3.19_ 一、实验要求(1)自行编写代码计算灰度图像的直方图,自行编写代码,不用matlab里面的直方图函数。
(2)用matlab读取和显示二、实验代码function ladylenna()a=imread('C:\lenna.jpg'); %读取图像至工作空间imfinfo('C:\lenna.jpg') %查看图像信息subplot(2,2,1);imshow(a);title('lady-lenna');if isrgb(a);b=rgb2gray(a); %RGB转换为灰度图像endsubplot(2,2,2);imshow(b); %显示图像title('ladygaga-lenna');[m,n]=size(a); %返回图像大小e=zeros(1,256);for k=0:255for i=1:mfor j=1:nif a(i,j)==ke(k+1)=e(k+1)+1; %灰度值相同的进行累加endendendendsubplot(2,2,4);bar(e); %画图像的灰度直方图title('灰度直方图');c=imrotate(a,20); %图像的旋转subplot(2,2,3);imshow(c);三、实验结果截图并做分析分析:第一幅图,lady-lenna是用imread函数读入,imshow显示为彩色图像。
第二幅图,ladygaga-lenna为变换后的灰度图,运用函数rgb2gray。
第三幅图是对原图像进行旋转所得,运用函数imrotate。
最后一幅为灰度直方图,采用自编函数。
小结:实验中由于必须使用自编函数,所以没有用到hist函数。
本次实验程序是在M文件中编写运行和调试的,在实验中开始由于没有用到函数rgb2gray,所以得到的结果有些出入。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
vc++编程实现显示灰度直方图的详细步骤步骤和程序:打开VC程序——文件——新建——工程中的MFC AppWizard(exe),在工程下面的框中输入工程名(假定工程名为111),点确定——选多重文档,点下一个——后面都点下一个直到完成确定,基本框架就完成了,下面就加代码。
这时VC界面上左边框的下面有三个按钮:ClassView、ResourceView和FileView,ClassView里面是工程111的类:CAdoutDlg、CChildFrame、CMy111App、CMy111Doc、CMy111View和Globals;点ResourceView里面是资源类:Accelerator、Dialog、Icon、Menu、String Table、Toolbar和Version;点开FileView里面是文件类:Source File、Header Files、Resource Files和ReadMe.txt。
点界面的“工程”按钮——添加工程——新建——选C++ Source File,在文件下面的框里输入文件名(如DIBAPI),点“结束”,这样在FileView中的Source Files里面就多了一个DIBAPI.cpp文件,所有的代码都加在该文件中。
再点界面的“工程”按钮——添加工程——新建——选C/C++ Header File,在文件下面的框里输入文件名(和前面的文件名必须一致),点“结束”,这样在FileView中的Header Files里面就多了一个DIBAPI.h文件,该文件是DIBAPI.cpp的头文件。
点开DIBAPI.h文件,里面是空白的,把如下代码考入文件中://DIBAPI.h#ifndef _INC_DIBAPI#define _INC_DIBAPIDECLARE_HANDLE(HDIB);#define PALVERSION 0x300#define IS_WIN30_DIB(lpbi) ((*(LPDWORD)(lpbi))==sizeof(BITMAPINFOHEADER))#define RECTWIDTH(lpRect) ((lpRect)->right-(lpRect)->left)#define RECTHEIGHT(lpRect) ((lpRect)->bottom-(lpRect)->top)#define WIDTHBYTES(bits) (((bits)+31)/32*4)#define DIB_HEADER_MARKER ((WORD)('M'<<8)|'B')BOOL WINAPI PaintDIB(HDC,LPRECT,HDIB,LPRECT,CPalette* pPal);BOOL WINAPI CreateDIBPalette(HDIB hDIB,CPalette* cPal);LPSTR WINAPI FindDIBBits(LPSTR lpbi);DWORD WINAPI DIBWidth(LPSTR lpDIB);DWORD WINAPI DIBHeight(LPSTR lpDIB);WORD WINAPI PaletteSize(LPSTR lpbi);WORD WINAPI DIBNumColors(LPSTR lpbi);HGLOBAL WINAPI CopyHandle(HGLOBAL h);BOOL WINAPI SaveDIB(HDIB hDib,CFile& file);HDIB WINAPI ReadDIBFile(CFile& file);//在此处输入自己的函数声明#endif//!_INC_DIBAPI上面这些函数是实现图像的读取、存储等图像处理的基本功能的,你将自己需要的函数也输入到“//在此处输入自己的函数声明”的下面。
点开DIBAPI.cpp文件,里面是空白的,将如下代码加入其中://DIBAPI.cpp#include "stdafx.h"#include "DIBAPI.h"WORD WINAPI DIBNumColors(LPSTR lpbi){WORD wBitCount;if(IS_WIN30_DIB(lpbi)){DWORD dwClrUsed;dwClrUsed=((LPBITMAPINFOHEADER)lpbi)->biClrUsed;if(dwClrUsed)return (WORD)dwClrUsed;}if(IS_WIN30_DIB(lpbi))wBitCount=((LPBITMAPINFOHEADER)lpbi)->biBitCount;elsewBitCount=((LPBITMAPCOREHEADER)lpbi)->bcBitCount;switch(wBitCount){case 1:return 2;case 4:return 16;case 8:return 256;default:return 0;}}WORD WINAPI PaletteSize(LPSTR lpbi){if(IS_WIN30_DIB(lpbi))return (WORD)(DIBNumColors(lpbi)*sizeof(RGBQUAD));elsereturn (WORD)(DIBNumColors(lpbi)*sizeof(RGBTRIPLE));}LPSTR WINAPI FindDIBBits(LPSTR lpbi){return (lpbi+*(LPDWORD)lpbi+::PaletteSize(lpbi));}DWORD WINAPI DIBWidth(LPSTR lpDIB){LPBITMAPINFOHEADER lpbmi;LPBITMAPCOREHEADER lpbmc;lpbmi=(LPBITMAPINFOHEADER)lpDIB;lpbmc=(LPBITMAPCOREHEADER)lpDIB;if(IS_WIN30_DIB(lpDIB))return lpbmi->biWidth;elsereturn (DWORD)lpbmc->bcWidth;}DWORD WINAPI DIBHeight(LPSTR lpDIB){LPBITMAPINFOHEADER lpbmi;LPBITMAPCOREHEADER lpbmc;lpbmi=(LPBITMAPINFOHEADER)lpDIB;lpbmc=(LPBITMAPCOREHEADER)lpDIB;if(IS_WIN30_DIB(lpDIB))return lpbmi->biHeight;elsereturn (DWORD)lpbmc->bcHeight;}BOOL WINAPI PaintDIB(HDC hDC,LPRECT lpDCRect,HDIB hDIB,LPRECT lpDIBRect,CPalette* pPal) {LPSTR lpDIBHdr;LPSTR lpDIBBits;BOOL bSuccess=FALSE;HPALETTE hPal=NULL;HPALETTE hOldPal=NULL;if(hDIB==NULL)return FALSE;lpDIBHdr=(LPSTR)::GlobalLock((HGLOBAL)hDIB);lpDIBBits=FindDIBBits(lpDIBHdr);if(pPal!=NULL){hPal=(HPALETTE)pPal->m_hObject;hOldPal=::SelectPalette(hDC,hPal,TRUE);}::SetStretchBltMode(hDC,COLORONCOLOR);if((RECTWIDTH(lpDCRect)==RECTWIDTH(lpDIBRect))&&(RECTHEIGHT(lpDCRect)==RECTHEIGHT( lpDIBRect))){bSuccess=::SetDIBitsToDevice(hDC,lpDCRect->left,lpDCRect->top,RECTWIDTH(lpDCRect),RECTHEI GHT(lpDCRect),lpDIBRect->left,\(int)DIBHeight(lpDIBHdr)-lpDIBRect->top-RECTHEIGHT(lpDIBRect),0,(WORD)DIBHeight(lpDIBHdr),\ lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS);}else{bSuccess=::StretchDIBits(hDC,lpDCRect->left,lpDCRect->top,RECTWIDTH(lpDCRect),RECTHEIGHT(l pDCRect),lpDIBRect->left,\lpDIBRect->top,RECTWIDTH(lpDIBRect),RECTHEIGHT(lpDIBRect),\lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);}::GlobalUnlock((HGLOBAL)hDIB);if(hOldPal)::SelectPalette(hDC,hOldPal,TRUE);GlobalUnlock(hDIB);return bSuccess;}BOOL WINAPI CreateDIBPalette(HDIB hDIB,CPalette* pPal){LPLOGPALETTE lpPal;HANDLE hLogPal;HPALETTE hPal=NULL;LPSTR lpbi;LPBITMAPINFO lpbmi;LPBITMAPCOREINFO lpbmc;BOOL bWinStyleDIB;int i;WORD wNumColors;BOOL bResult=FALSE;if(hDIB==NULL)return FALSE;lpbi=(LPSTR)::GlobalLock((HGLOBAL)hDIB);lpbmi=(LPBITMAPINFO)lpbi;lpbmc=(LPBITMAPCOREINFO)lpbi;wNumColors=DIBNumColors(lpbi);bWinStyleDIB=IS_WIN30_DIB(lpbi);if(wNumColors!=0){hLogPal=::GlobalAlloc(GHND,sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*wNumColors); if(hLogPal==0){::GlobalUnlock((HGLOBAL)hDIB);return FALSE;}lpPal=(LPLOGPALETTE)::GlobalLock(hLogPal);lpPal->palVersion=PALVERSION;lpPal->palNumEntries=(WORD)wNumColors;bWinStyleDIB=IS_WIN30_DIB(lpbi);for(i=0;i<(int)wNumColors;i++){if(bWinStyleDIB){lpPal->palPalEntry[i].peRed=lpbmi->bmiColors[i].rgbRed;lpPal->palPalEntry[i].peGreen=lpbmi->bmiColors[i].rgbGreen;lpPal->palPalEntry[i].peBlue=lpbmi->bmiColors[i].rgbBlue;lpPal->palPalEntry[i].peFlags=0;}else{lpPal->palPalEntry[i].peRed=lpbmc->bmciColors[i].rgbtRed;lpPal->palPalEntry[i].peGreen=lpbmc->bmciColors[i].rgbtGreen;lpPal->palPalEntry[i].peBlue=lpbmc->bmciColors[i].rgbtBlue;lpPal->palPalEntry[i].peFlags=0;}}bResult=pPal->CreatePalette(lpPal);::GlobalUnlock((HGLOBAL)hLogPal);::GlobalFree((HGLOBAL)hLogPal);::GlobalUnlock((HGLOBAL)hDIB);return bResult;}HGLOBAL WINAPI CopyHandle(HGLOBAL h){if(h==NULL)return NULL;DWORD dwLen=::GlobalSize((HGLOBAL)h);HGLOBAL hCopy=::GlobalAlloc(GHND,dwLen);if(hCopy!=NULL){void* lpCopy=::GlobalLock((HGLOBAL)hCopy);void* lp=::GlobalLock((HGLOBAL)h);memcpy(lpCopy,lp,dwLen);::GlobalUnlock(hCopy);::GlobalUnlock(h);}return hCopy;}BOOL WINAPI SaveDIB(HDIB hDib,CFile& file){BITMAPFILEHEADER bmfHdr;LPBITMAPINFOHEADER lpBI;DWORD dwDIBSize;if(!hDib)return FALSE;lpBI=(LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL)hDib);if(lpBI==NULL)return FALSE;if(!IS_WIN30_DIB(lpBI)){::GlobalUnlock((HGLOBAL)hDib);return FALSE;}bmfHdr.bfType=DIB_HEADER_MARKER;dwDIBSize=*(LPDWORD)lpBI+::PaletteSize((LPSTR)lpBI);if((lpBI->biCompression==BI_RLE8)||(lpBI->biCompression==BI_RLE4)) dwDIBSize+=lpBI->biSizeImage;elseDWORD dwBmBitsSize;dwBmBitsSize=WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount))*lpBI->biHeight; dwDIBSize+=dwBmBitsSize;lpBI->biSizeImage=dwBmBitsSize;}bmfHdr.bfSize=dwDIBSize+sizeof(BITMAPFILEHEADER);bmfHdr.bfReserved1=0;bmfHdr.bfReserved2=0;bmfHdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+lpBI->biSize+::PaletteSize((LPSTR)lpBI); TRY{file.Write((LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER));file.WriteHuge(lpBI,dwDIBSize);}CATCH(CFileException,e){::GlobalUnlock((HGLOBAL)hDib);THROW_LAST();}END_CATCH::GlobalUnlock((HGLOBAL)hDib);return TRUE;}HDIB WINAPI ReadDIBFile(CFile& file){BITMAPFILEHEADER bmfHeader;DWORD dwBitsSize;HDIB hDIB;LPSTR pDIB;dwBitsSize=file.GetLength();if(file.Read((LPSTR)&bmfHeader,sizeof(bmfHeader))!=sizeof(bmfHeader))return NULL;if(bmfHeader.bfType!=DIB_HEADER_MARKER)return NULL;hDIB=(HDIB)::GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,dwBitsSize);if(hDIB==0)return NULL;pDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);if(file.ReadHuge(pDIB,dwBitsSize-sizeof(BITMAPFILEHEADER))!=dwBitsSize-sizeof(BITMAPFILEHEA DER)){::GlobalUnlock((HGLOBAL)hDIB);::GlobalFree((HGLOBAL)hDIB);return NULL;}::GlobalUnlock((HGLOBAL)hDIB);return hDIB;}//在此处输入自己的函数定义上面是DIBAPI.h头文件中声明的函数的定义,你将自己的函数定义加到“//在此处输入自己的函数定义”后面。