windows截图c语言,window 截取屏幕,并实现jpeg压缩
1)头文件
#include "stdafx.h"
#include
#include
#include
#pragma comment(lib,"jpeglib/libjpeg.lib")
#include "jpeglib/jpeglib.h"
2)window 截屏函数
int GetScreenBitMap(int x,int y,int w,int h,BYTE *dataBuf)
{
if(w<0||h<0)
{
return 0;//异常
}
HWND hWnd = GetDesktopWindow();//获得屏幕的HWND.
HDC hScreenDC = GetDC(hWnd); //获得屏幕的HDC.
HDC MemDC = CreateCompatibleDC(hScreenDC);
HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC,w,h);//改成创建的幕布的大小。
HGDIOBJ hOldBMP = SelectObject(MemDC,hBitmap);
BitBlt(MemDC,0,0,w,h,hScreenDC,x,y,SRCCOPY);//改变截屏大小,从全屏改成
SelectObject(MemDC,hOldBMP);
DeleteObject(MemDC);
ReleaseDC(hWnd,hScreenDC);
WriteBmpToBuf( hBitmap,dataBuf);
return 1;
}
3)将BitMap转换为Byte
void WriteBmpToBuf(HBITMAP hBitmap,BYTE *dataBuf)
{
const char name_type[8]="DISPLAY";
HDC hDC =CreateDC((LPCWSTR)name_type,NULL,NULL,NULL);
int iBits ;
BITMAP bm; //位图属性结构
GetObject(hBitmap, sizeof(bm), (LPSTR)&bm);
iBits=bm.bmBitsPixel;
WORD wBitCount; //位图中每个像素所占字节数
if (iBits <= 1)
wBitCount = 1;
else if (iBits <= 4)
wBitCount = 4;
else if (iBits <= 8)
wBitCount = 8;
else if (iBits <= 24)
wBitCount = 24;
else
wBitCount = iBits;
DWORD dwPaletteSize=0; //调色板大小, 位图中像素字节大小
if (wBitCount <= 8)
dwPaletteSize = (1 <
BITMAPINFOHEADER bi,bi1; //位图信息头结构
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB; //BI_RGB表示位图没有压缩
bi.biSizeImage = bm.bmWidthBytes* bm.bmHeight;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
DWORD dwBmBitsSize = ((bm.bmWidth * wBitCount+31)/32) * 4 * bm.bmHeight;
HANDLE hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER)); //为位图内容分配内存
LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi;
HANDLE hPal = GetStockObject(DEFAULT_PALETTE); // 处理调色板
HANDLE hOldPal=NULL;
if (hPal)
{
hDC = GetDC(NULL);
hOldPal = SelectPalette(hDC,(HPALETTE)hPal, FALSE);
RealizePalette(hDC);
}
int nOutputBytes = 0;
GetDIBits(hDC, hBitmap, 0, (UINT) bm.bmHeight,(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,(BITMAPINFO*)lpbi,DIB_RGB_COLORS);// 获取该调色板下新的像素值
if (hOldPal)//恢复调色板
{
SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
}
if(dwBmBitsSize!=strlen((char *)dataBuf))
{
free(dataBuf);
dataBuf=0;
dataBuf = (BYTE *)malloc(dwBmBitsSize);
}
memcpy(dataBuf,(LPSTR)lpbi+sizeof(BITMAPINFOHEADER)+dwPaletteSize, dwBmBitsSize);
GlobalUnlock(hDib); //清除
GlobalFree(hDib);
return ;
/*
//保存到本地文件中 一
BITMAPFILEHEADER bmfHdr; //位图文件头结构
bmfHdr.bfType = 0x4D42; // "BM" // 设置位图文件头
DWORD dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
savaFile("test.bmp",(BYTE *)&bmfHdr, sizeof(BITMAPFILEHEADER));
savaFile("test.bmp",(BYTE *)lpbi, dwBmBitsSize);
*/
/*
//保存到本地文件中 二
HANDLE hFile = CreateFile((LPCWSTR)strFileName1, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);//创建位图文件
DWORD dwWritten;
WriteFile(hFile, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL); // 写入位图文件头
WriteFile(hFile, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);// 写入位图文件其余内容
CloseHandle(hFile);
*/
/*
//保存到内存 只需要数据段
p_w_picpath_buffer = new BYTE [dwDIBSize];
memcpy(p_w_picpath_buffer,(LPSTR)lpbi+sizeof(BITMAPINFOHEADER)+dwPaletteSize, dwBmBitsSize);
*/
//文件头和数据段都要
// p_w_picpath_buffer = new BYTE [sizeof(BITMAPFILEHEADER) + dwDIBSize];
// memcpy(p_w_picpath_buffer,(LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
// memcpy(p_w_picpath_buffer+sizeof(BITMAPFILEHEADER),(LPSTR)lpbi, dwDIBSize);
//savaFile(p_w_picpath_buffer,sizeof(BITMAPFILEHEADER) + dwDIBSize);
}
4) jpeg压缩 (保存到缓冲)
BOOL BmpToJpg( int nWidth, int nHeight, int nPixelBytes, BYTE* byBmpData, BYTE** byJpgData, unsigned long* nSize )
{
int i,j;
for (i=0,j=0; j
{
*(byBmpData+i)=*(byBmpData+j+2);
*(byBmpData+i+1)=*(byBmpData+j+1);
*(byBmpData+i+2)=*(byBmpData+j);
}
BOOL bResult = FALSE;
jpeg_compress_struct jCompress;
jpeg_error_mgr jErrorMgr;
jCompress.err = jpeg_std_error( &jErrorMgr );
jpeg_create_compress( &jCompress );
jpeg_mem_dest( &jCompress, byJpgData, nSize );
jCompress.p_w_picpath_width = nWidth;
jCompress.p_w_picpath_height = nHeight;
jCompress.input_components = nPixelBytes;
jCompress.in_color_space = JCS_RGB;
jpeg_set_defaults( &jCompress );
jpeg_set_quality ( &jCompress, JPEG_QUALITY, true );
jpeg_start_compress( &jCompress, true );
int nLineWidth = nWidth * nPixelBytes;
for ( int i = 0; i
{
BYTE* lpJpgBits = byBmpData + ( nHeight - i - 1 ) * nLineWidth;
JSAMPROW row_pointer = lpJpgBits;
jpeg_write_scanlines( &jCompress, &row_pointer, 1 );
}
jpeg_finish_compress( &jCompress );
jpeg_destroy_compress( &jCompress );
return bResult;
}
5)jpeg压缩 保存成文件
int savejpegToFile(char *filename, unsigned char *bits, int width, int height, int depth)
{
//RGB值切换
int i,j;
for (i=0,j=0; j
{
*(bits+i)=*(bits+j+2);
*(bits+i+1)=*(bits+j+1);
*(bits+i+2)=*(bits+j);
}
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE * outfile; /* target file */
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
int row_stride; /* physical row width in p_w_picpath buffer */
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
if ((outfile = fopen(filename, "wb")) == NULL) {
fprintf(stderr, "can't open %s/n", filename);
return -1;
}
jpeg_stdio_dest(&cinfo, outfile);
cinfo.p_w_picpath_width = width; /* p_w_picpath width and height, in pixels */
cinfo.p_w_picpath_height = height;
cinfo.input_components = 3; /* # of color components per pixel */
cinfo.in_color_space = JCS_RGB; /* colorspace of input p_w_picpath */
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, JPEG_QUALITY, TRUE /* limit to baseline-JPEG values */);
jpeg_start_compress(&cinfo, TRUE);
row_stride = width * 3; /* JSAMPLEs per row in p_w_picpath_buffer */
while (cinfo.next_scanline
//由于jpg文件的图像是倒的,所以改了一下读的顺序
row_pointer[0] = & bits[(cinfo.p_w_picpath_height - cinfo.next_scanline - 1) * row_stride];
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(outfile);
jpeg_destroy_compress(&cinfo);
return 0;
}
6)调用test
#define JPEG_QUALITY 100 //它的大小决定jpg的质量好坏
void testScreen()
{
int width = GetSystemMetrics ( SM_CXSCREEN );
int height= GetSystemMetrics ( SM_CYSCREEN );
BYTE *p_w_picpath_buffer = (BYTE *)malloc(width * height * 4);//指向位图buffer的全局指针,window下像素格式: BGRA(4个字节)
GetScreenBitMap(0,0,width,height,p_w_picpath_buffer);
//savejpegToFile("test.jpg", p_w_picpath_buffer, width, height, 3);
//unsigned char * savabuf=(unsigned char *)malloc(width*height*4);
// SaveJpegToBuf(savabuf,p_w_picpath_buffer,width,height,3);
unsigned long nSize=10;
BYTE * savabuf=(BYTE *)malloc(nSize);
BmpToJpg(width,height,3,p_w_picpath_buffer,&savabuf,&nSize);
savaFile("123.jpg",savabuf,(long)nSize);
delete [] p_w_picpath_buffer;
}
windows截图c语言,window 截取屏幕,并实现jpeg压缩相关推荐
- 【Flutter 问题系列第 22 篇】在 Flutter 中如何截取屏幕并显示到页面中,以及如何将截图保存到相册
这是[Flutter 问题系列第 22 篇],如果觉得有用的话,欢迎关注专栏. 关于在 Flutter 中如何截取屏幕,以及如何将截图保存到相册的文章少之又少,即使有,也是错误一大片,有的甚至运行后都 ...
- 易语言快照和截取屏幕区域
本课录制了两个和截图有关的易语言命令,快照和截取屏幕区域,并且分快照窗口快照,全屏快照,保存快照,已经截屏区域等等. 视频链接: 511遇见易语言教程 一.快照() 主要用于截图 1.窗口快照 2.全 ...
- 计算机桌面位置在哪显示器,笔记本电脑怎么截取屏幕 笔记本截图位置在哪
现在越来越多的电脑用户选择笔记本,不仅方便携带,功能上也不弱于台式有电脑,有时候我们在使用电脑的时候经常需要截取屏幕,可是在笔记本电脑中怎么截屏呢?其实很简单,下面小编为大家带来笔记本电脑截取屏幕的详 ...
- [转]Ubuntu使用 gnome-screenshot 截图命令来截取屏幕、窗口或指定区
在Ubuntu系统下,当有需要截图时一般会直接按键盘上的PrtScn SysRq键或者Ctrl+PrtScn键截取当前窗口,但最近发现,在顶栏menu打开的状态下是无法用这种方法截屏的,菜单弹出时按P ...
- windows截图快捷键_使用快捷键打开并使用Windows截图工具
windows截图快捷键 Snippingtool used used to take screenshot in windows operating systems. Snipping tool i ...
- windows截图功能
windows截图功能(Win10) 1.截全屏并保存 键盘上敲 windows+prt sc sysrq 自动保存在路径下C:\Users\www\Pictures\Screenshots ...
- python测试脚本截图_Python+selenium实现截图图片并保存截取的图片
这篇文章介绍如何利用Selenium的方法进行截图,在测试过程中,是有必要截图,特别是遇到错误的时候进行截图.在selenium for Python中主要有三个截图方法,我们挑选其中最常用的一种. ...
- windows截图指令命令/cmd中截图指令
Windows自带的命令行是没有的啦!要下载一个nircmd的程序,使用起来非常方便~ 添加到环境变量中 命令: 截取整个屏幕 nircmd savescreenshot F:\\tmp.png 截取 ...
- C# 模拟PrintScreen 和 Alt+PrintScreen截取屏幕图片
C# 模拟PrintScreen 和 Alt+PrintScreen截取屏幕图片 keybd_event API 函数功能:该函数合成一次击键事件.系统可使用这种合成的击键事件来产生WM_KEYUP或 ...
最新文章
- 机器学习 TOP 10 必读论文 | 资源
- Xamarin XAML语言教程构建ControlTemplate控件模板 (三)
- Apache检查配置文件语法
- [置顶] 设计模式之六大原则——单一职责原则(SRP)
- 人工智能免费学习!想了解的进来看看
- 千字谏言!Python入门:这两点绝对不能偷懒!否则工作后必后悔
- 关联的两个字段度需要建立索引吗_索引那些事儿
- Cordova安装与配置过程中出现的问题及解决办法
- Code4Fun: 通过XML模板系统实现对象的灵活序列化
- 基本的 Python socket 模块
- 3D相机成像原理简介
- 计算机视觉教程章毓晋课后答案6,计算机视觉教程 教学课件 章毓晋 CCV01.pdf
- AndroidStudio安装之后虚拟机启动失败解决方法
- HTML5 video autoplay=autoplay 无法自动播放的问题
- ZOJ 3939 The Lucky Week
- 一种简单的将图一-1变成图1-1的方式
- 沃信科技T3 Sota安装配置手册(1-4章)
- 苹果手机编辑word_苹果手机更新后卡顿,关闭这两个开关立马恢复,设置之后差点泪崩...
- 第一个被赋予公明身份的机器人_世界首位获公民身份机器人索菲亚,称要结婚生子毁灭人类...
- 在Windows 使用Administrator账户
热门文章
- C语言cJSON库的使用,解析json数据格式
- Pure公司发布机架规模FlashBlade对象与文件存储方案
- Java多线程基础篇(02)-多线程的实现
- JSP基础之 C标签中的 varStatues属性
- Symfony1.4.11学习笔记(四):数据模型
- dos批处理命令详解(转)
- dreamcast游戏_《Dreamcast Collection》开箱及游戏介绍
- oracle if 使用函数,Oracle 常见函数用法
- java collection源码_jdk源码阅读Collection实例分析
- Zookeeper常用命令详解(Zookeeper3.6)