Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C++屏幕截图 图片转JPEG

C++屏幕截图 图片转JPEG

作者头像
码客说
发布于 2021-07-13 03:22:17
发布于 2021-07-13 03:22:17
2.4K10
代码可运行
举报
文章被收录于专栏:码客码客
运行总次数:0
代码可运行

前言

C#实现同屏的时候,频繁截屏内存并不能很好的释放,所以就打算用C++实现这部分的功能。

这里图片的压缩用到了JpegLib, JpegLib是一个用C编写的jpeg图像压缩免费库,许多应用程序对jepg的支持都依赖于该库。

编译库

下载

下载地址:https://www.ijg.org/

官方下载地址:jpegsr9d.zip

百度云链接:https://pan.baidu.com/s/13xhEjxWR9b6Bx7OL6tLTIw 提取码:6owy

编译

使用Vistual studio的命令行工具进入源码文件夹

如图

注意

不要用系统的CMD或者Powershell,无法编译。

源码中复制一份jconfig.vc,改变后缀变为jconfig.h

执行如下命令

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
nmake -f makefile.vc

提示找不到win32.mak文件,在C盘搜索这个文件名,没有发现该文件,可以直接下一个

链接:https://pan.baidu.com/s/1y-uAsb5e6KdWFRgY3MxaKg 提取码:kn30 把·win32.mak放在源码目录下即可(Win10环境下需要下载)

编译成功后再项目下创建libjpeg文件夹,里面再创建includelib

把编辑后的libjpeg.lib放在lib目录下,所有的.h的头文件放在include

处理好的文件如下

链接:https://pan.baidu.com/s/1vEjL6CHgFDuqQioLq3dhJw 提取码:qeb3

项目下引用

项目下创建modules文件夹,把之前的libjpeg文件夹放进来

项目右键属性

C/C++常规中的附加包含目录中添加modules\libjpeg\include

链接器=>常规=>附加库文件中添加modules\libjpeg\lib

链接器=>输入=>附加依赖项中添加libjpeg.lib

这样项目中就可以调用了

Bmp2Jpeg.h

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#pragma once

class CBmp2Jpeg
{
public:
	CBmp2Jpeg();
	~CBmp2Jpeg();

public:
	int Bmp2Jpeg(const char* bmp, const char* jpeg);

private:
	int SaveJpeg(const char* filename, unsigned char* bits, int width, int height, int depth);
	int ReadBmp(const char* bmp, unsigned char** data, int& w, int& h, int& d);
	void Bgra2Rgb(const unsigned char* src, int w, int h, int d, unsigned char* dst);
	void InitFileHeader(void* pFile, void* fileHeader);
	void InitInfoHeader(void* pFile, void* infoHeader);
	void SaveBmp(void* fileHeader, void* infoHeader, int bitCount, unsigned char* data, const char* savename);
private:
	int	m_quality;	//它的大小决定jpg的质量好坏

	enum {
		JPEG_QUALITY = 100,
	};
};

Bmp2Jpeg.cpp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include<Windows.h>
#include <fstream>
#include <stdlib.h>
#include "Bmp2Jpeg.h"
#include <vector>

extern "C"
{
#include "jpeglib.h"
};

#pragma comment(lib,"libjpeg.lib")

using namespace std;

#pragma pack(2)

struct bmp_fileheader   //文件头,长度为14Byte固定
{
	unsigned short bfType;
	unsigned long bfSize;
	unsigned short bfReserved1;
	unsigned short bfReserved2;
	unsigned long bfOffBits;
};

struct bmp_infoheader  //文件信息头,长度为40Byte固定
{
	unsigned long biSize;
	unsigned long biWidth;
	unsigned long biHeight;
	unsigned short biPlanes;
	unsigned short biBitCount;
	unsigned long biCompression;
	unsigned long biSizeImage;
	unsigned long biXPelsPerMeter;
	unsigned long biYPelsPerMeter;
	unsigned long biClrUsed;
	unsigned long biClrImportant;
};

struct RGBPallete
{
	unsigned char b;
	unsigned char g;
	unsigned char r;
	unsigned char alpha;
};

CBmp2Jpeg::CBmp2Jpeg() :
	m_quality(JPEG_QUALITY)
{
}

CBmp2Jpeg::~CBmp2Jpeg()
{
}
/*===================================================================================
function:       jpeg压缩
input:          1:生成的文件名,2:bmp的指针,3:位图宽度,4:位图高度,5:颜色深度
return:         int
description:    bmp的像素格式为(RGB)
===================================================================================*/
int CBmp2Jpeg::SaveJpeg(const char* filename, unsigned char* bits, int width, int height, int depth)
{
	FILE* outfile;                 /* target file */
	fopen_s(&outfile, filename, "wb");
	if (outfile == NULL) {
		return -1;
	}

	struct jpeg_compress_struct cinfo;
	struct jpeg_error_mgr jerr;

	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_compress(&cinfo);

	jpeg_stdio_dest(&cinfo, outfile);

	cinfo.image_width = width;      /* image width and height, in pixels */
	cinfo.image_height = height;
	cinfo.input_components = 3;         /* # of color components per pixel */
	cinfo.in_color_space = JCS_RGB;         /* colorspace of input image */

	jpeg_set_defaults(&cinfo);
	jpeg_set_quality(&cinfo, m_quality, TRUE /* limit to baseline-JPEG values */);

	jpeg_start_compress(&cinfo, TRUE);

	JSAMPROW row_pointer[1];        /* pointer to JSAMPLE row[s] */
	int     row_stride;             /* physical row width in image buffer */
	row_stride = width * depth; /* JSAMPLEs per row in image_buffer */

	while (cinfo.next_scanline < cinfo.image_height) {
		//这里我做过修改,由于jpg文件的图像是倒的,所以改了一下读的顺序
		//row_pointer[0] = & bits[cinfo.next_scanline * row_stride];
		row_pointer[0] = &bits[(cinfo.image_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;
}

void CBmp2Jpeg::InitFileHeader(void* pFile, void* fileHeader)
{
	bmp_fileheader* pfileHeader = (bmp_fileheader*)fileHeader;
	fstream* filein = (fstream*)pFile;
	//初始化文件头
	pfileHeader->bfType = 0;
	pfileHeader->bfSize = 0;
	pfileHeader->bfReserved1 = 0;
	pfileHeader->bfReserved2 = 0;
	pfileHeader->bfOffBits = 0;
	//读位图文件头并输出相应信息
	filein->read((char*)fileHeader, sizeof(bmp_fileheader));
}

void CBmp2Jpeg::InitInfoHeader(void* pFile, void* infoHeader)
{
	bmp_infoheader* pinfoHeader = (bmp_infoheader*)infoHeader;
	fstream* filein = (fstream*)pFile;
	//初始化信息头
	pinfoHeader->biSize = 0;
	pinfoHeader->biWidth = 0;
	pinfoHeader->biHeight = 0;
	pinfoHeader->biPlanes = 0;
	pinfoHeader->biBitCount = 0;
	pinfoHeader->biCompression = 0;
	pinfoHeader->biSizeImage = 0;
	pinfoHeader->biXPelsPerMeter = 0;
	pinfoHeader->biYPelsPerMeter = 0;
	pinfoHeader->biClrUsed = 0;
	pinfoHeader->biClrImportant = 0;

	//读位图信息头并输出相应信息
	filein->read((char*)infoHeader, sizeof(bmp_infoheader));
}

void CBmp2Jpeg::SaveBmp(void* fileHeader, void* infoHeader, int bitCount, unsigned char* data, const char* savename)
{
	bmp_fileheader* pfileHeader = (bmp_fileheader*)fileHeader;
	bmp_infoheader* pinfoHeader = (bmp_infoheader*)infoHeader;
	//写入文件
	std::string str(savename);
	str.append(".bmp");
	fstream fileout;
	fileout.open(str, std::ios::binary | std::ios::out);
	fileout.write((char*)fileHeader, sizeof(bmp_fileheader));
	fileout.write((char*)infoHeader, sizeof(bmp_infoheader));
	fileout.write((char*)data, sizeof(unsigned char) * pfileHeader->bfSize - pfileHeader->bfOffBits);

	fileout.close();
}

//读取并将图片另存为一个新文件, 转换成rgb格式
int CBmp2Jpeg::ReadBmp(const char* bmp, unsigned char** data, int& w, int& h, int& d)
{
	//打开位图文件
	fstream filein;
	filein.open(bmp, std::ios::binary | std::ios::in);
	if (!filein.is_open())
	{
		char clog[256] = { 0 };
		sprintf_s(clog, sizeof(clog), "bmp转jpeg,找不到 %s\n", bmp);
		OutputDebugStringA(clog);
		return -1;
	}

	//定义变量
	long width = 0;
	long height = 0;
	long bitCount = 0;

	bmp_fileheader  fileHeader;
	bmp_infoheader  infoHeader;

	InitFileHeader(&filein, &fileHeader);

	if (fileHeader.bfType != 0x4d42)
	{
		filein.close();
		return -1;
	}

	InitInfoHeader(&filein, &infoHeader);

	width = infoHeader.biWidth;
	height = infoHeader.biHeight;
	bitCount = infoHeader.biBitCount;

	int bitPerLine = ((width * bitCount + 31) >> 5) << 2;
	int imgSize = abs(height * bitPerLine);
	int imgReal = fileHeader.bfSize - fileHeader.bfOffBits;
	if (imgSize != imgReal)
	{
		char clog[256] = { 0 };
		sprintf_s(clog, sizeof(clog), "bmp转jpeg,图像尺寸不对\n");
		OutputDebugStringA(clog);
		filein.close();
		return -1;
	}

	if (bitCount == 8)
	{
		std::vector<RGBPallete> palletes;
		unsigned char buf[256 * sizeof(RGBPallete)];

		filein.read((char*)buf, 256 * sizeof(RGBPallete));

		for (int i = 0; i < 256; i++)
		{
			RGBPallete pallete;
			memcpy(&pallete, buf + i * sizeof(RGBPallete), sizeof(RGBPallete));

			palletes.push_back(pallete);
		}

		unsigned char* pTemp = new unsigned char[imgSize];
		filein.read((char*)pTemp, imgSize);

		*data = new unsigned char[width * abs(height) * 4];
		for (int i = 0; i < imgSize; i++)
		{
			RGBPallete& p = palletes[pTemp[i]];
			memcpy((*data) + i * sizeof(RGBPallete), &p, sizeof(RGBPallete));
		}

		bitCount = 32;
		delete pTemp;
	}
	else if (bitCount == 24 || bitCount == 32)
	{
		*data = new unsigned char[imgSize];
		filein.read((char*)(*data), imgSize);
		filein.close();
	}
	else
	{
		filein.close();
		return -1;
	}

	w = width;
	h = height;
	d = bitCount;

	return 0;
}

void CBmp2Jpeg::Bgra2Rgb(const unsigned char* src, int w, int h, int d, unsigned char* dst)
{
	unsigned char* pTempDst = dst;
	for (int i = 0; i < abs(h); i++)
	{
		const unsigned char* pTempSrc = nullptr;
		if (h > 0)
		{
			pTempSrc = src + w * i * d;
		}
		else
		{
			pTempSrc = src + w * abs(i + h + 1) * d;
		}

		for (int j = 0; j < w; j++)
		{
			*(pTempDst) = *(pTempSrc + 2);
			*(pTempDst + 1) = *(pTempSrc + 1);
			*(pTempDst + 2) = *(pTempSrc);
			pTempDst += 3;
			pTempSrc += d;
		}
	}
}

int CBmp2Jpeg::Bmp2Jpeg(const char* bmp, const char* jpeg)
{
	unsigned char* brga = nullptr; //指向位图buffer的全局指针,window下像素格式: BGRA(4个字节)
	int width = 0, height = 0, depth = 0;

	if (ReadBmp(bmp, &brga, width, height, depth) < 0)
	{
		return -1;
	}

	unsigned char* rgb = new unsigned char[width * abs(height) * depth / 8];
	Bgra2Rgb(brga, width, height, depth / 8, rgb);

	int ret = SaveJpeg(jpeg, rgb, width, abs(height), 3);

	delete[] brga;
	delete[] rgb;
	brga = nullptr;
	rgb = nullptr;
	return ret;
}

附录

截屏

ScreenShot.h

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#pragma once
bool ScreenShot(const char* szSavePath);

ScreenShot.cpp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <Windows.h>
#include <stdio.h>
#include <tchar.h>

#include <iostream>
using namespace std;

#pragma warning(disable:4996)

#define TAG_DEV_PLAS  1
#define BITS_PER_PIX  32
#define NO_COLOR_TAB  0
#define UNCMP_RGB     0
#define H_RESOL_0     0
#define V_RESOL_0     0
#define ALL_COLOR     0

#define MUST_ZERO     0
#define TYPE_BMP      0x4D42

#define FILE_HEAD     sizeof(BITMAPFILEHEADER)
#define INFO_HEAD     sizeof(BITMAPINFOHEADER)
#define HEAD_SIZE     sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER)

bool ScreenShot(const char* szSavePath)
{
	//显示器屏幕
	HDC hCurrScreen = GetDC(NULL);

	//创建一个兼容的DC,在内存中表示当前位图的上下文
	HDC hCmpDC = CreateCompatibleDC(hCurrScreen);

	//宽高
	int iScreenWidth = GetDeviceCaps(hCurrScreen, HORZRES);
	int iScreenHeight = GetDeviceCaps(hCurrScreen, VERTRES);

	//当前屏幕位图
	HBITMAP hBmp = CreateCompatibleBitmap(hCurrScreen, iScreenWidth, iScreenHeight);

	//用当前位图句柄表示内存中屏幕位图上下文
	SelectObject(hCmpDC, hBmp);

	//将当前屏幕图像复制到内存中
	BOOL ret = BitBlt(hCmpDC, 0, 0, iScreenWidth, iScreenHeight, hCurrScreen, 0, 0, SRCCOPY);

	//BMP图像信息头
	BITMAPINFOHEADER hBmpInfo;
	hBmpInfo.biSize = INFO_HEAD;
	hBmpInfo.biWidth = iScreenWidth;
	hBmpInfo.biHeight = iScreenHeight;
	hBmpInfo.biPlanes = TAG_DEV_PLAS;
	hBmpInfo.biClrUsed = NO_COLOR_TAB;
	hBmpInfo.biBitCount = BITS_PER_PIX;
	hBmpInfo.biSizeImage = UNCMP_RGB;
	hBmpInfo.biCompression = BI_RGB;
	hBmpInfo.biClrImportant = ALL_COLOR;
	hBmpInfo.biXPelsPerMeter = H_RESOL_0;
	hBmpInfo.biYPelsPerMeter = V_RESOL_0;

	/* * * * * * * * * * * * * * * * * * * *
	 * Windows按4字节分配内存
	 * 首先计算每行所需要的bit数,并按4字节对齐
	 * 对齐后的数据乘4,从DWORD转为BYTE
	 * 每行实际所占BYTE乘图像列数得到数据源大小
	 * * * * * * * * * * * * * * * * * * * */
	DWORD dwSrcSize = ((iScreenWidth * hBmpInfo.biBitCount + 31) / 32) * 4 * iScreenHeight;

	//截图总大小
	DWORD dwPicSize = HEAD_SIZE + dwSrcSize;

	//BMP图像文件头
	BITMAPFILEHEADER hBmpFile;
	hBmpFile.bfSize = dwPicSize;
	hBmpFile.bfType = TYPE_BMP;
	hBmpFile.bfOffBits = HEAD_SIZE;
	hBmpFile.bfReserved1 = MUST_ZERO;
	hBmpFile.bfReserved2 = MUST_ZERO;

	//BMP图像数据源
	char* bmpSrc = new char[dwSrcSize];
	ZeroMemory(bmpSrc, dwSrcSize);

	//检索指定的兼容位图中的所有位元数据
	//并复制到指定格式的设备无关位图的缓存中
	GetDIBits(hCmpDC, hBmp, 0, (UINT)iScreenHeight, bmpSrc, (BITMAPINFO*)&hBmpInfo, DIB_RGB_COLORS);

	//汇总所有数据信息
	char* szBmp = new char[dwPicSize];
	ZeroMemory(szBmp, dwPicSize);
	memcpy(szBmp, (void*)&hBmpFile, FILE_HEAD);
	memcpy(szBmp + FILE_HEAD, (void*)&hBmpInfo, INFO_HEAD);
	memcpy(szBmp + HEAD_SIZE, bmpSrc, dwSrcSize);

	//保存BMP图像
	FILE* hFile = fopen(szSavePath, "wb+");
	if (nullptr != hFile)
	{
		size_t count = fwrite(szBmp, 1, dwPicSize, hFile);
		fclose(hFile);
	}

	//释放资源
	DeleteObject(hBmp);
	DeleteObject(hCmpDC);
	ReleaseDC(NULL, hCurrScreen);
	delete[] szBmp;
	delete[] bmpSrc;
	szBmp = nullptr;
	bmpSrc = nullptr;
	return true;
}

调用

main.cpp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <stdio.h>
#include "Bmp2Jpeg.h"
#include "ScreenShot.h"
using namespace std;
int main()
{
	ScreenShot("D:\\pic\\2.bmp");
	CBmp2Jpeg bmp;
	bmp.Bmp2Jpeg("D:\\pic\\2.bmp", "D:\\pic\\2.jpeg");
	cout << "success." << endl;
	cin.get();
	return 0;
}

查看DLL方法

特别注意

生成DLL一定要用Release环境!!! 生成DLL一定要用Release环境!!! 生成DLL一定要用Release环境!!! 否则会依赖的DLL也会用Debug的DLL,在普通用户的环境中是没有这些DLL的。

现在我们要把方法导出

直接在原来的解决方案中添加项目,把之前的.cpp.h复制过来,然后导出方法就行了

screenshot.def

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
LIBRARY screenshot
EXPORTS
ScreenShot @1,
MyBmp2Jpeg @2,

注意

文件名和LIBRARY screenshot都要和项目名保持一致 导出都要导出方法,不要导出类,导出类其他语言不支持,所以我们添加一个导出方法MyBmp2Jpeg

MyBmp2Jpeg.cpp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <stdio.h>
#include "../Bmp2Jpeg.h"

int MyBmp2Jpeg(const char* bmp, const char* jpeg) {
	CBmp2Jpeg mbmp;
	mbmp.Bmp2Jpeg(bmp, jpeg);
	return 0;
}

同一个解决方案下dll会自动生成在debug目录下,所以dll不用再设置引用

调用方式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <stdio.h>
#include <Windows.h>

using namespace std;

int main()
{
	typedef bool (*ScreenShot)(const char* szSavePath);
	typedef int (*MyBmp2Jpeg)(const char* bmp, const char* jpeg);
	HINSTANCE hDLL;
	ScreenShot mScreenShot;
	MyBmp2Jpeg mBmp2Jpeg;
	hDLL = LoadLibrary(TEXT("screenshot.dll"));
	if (hDLL != 0) {
		mScreenShot = (ScreenShot)GetProcAddress(hDLL, "ScreenShot");
		mBmp2Jpeg = (MyBmp2Jpeg)GetProcAddress(hDLL, "MyBmp2Jpeg");
		mScreenShot("D:\\pic\\003.bmp");
		mBmp2Jpeg("D:\\pic\\003.bmp", "D:\\pic\\003.jpeg");
		cout << "success." << endl;
		cin.get();
		FreeLibrary(hDLL);//卸载dll文件;
	}
	return 0;
}

在VS目录中搜索dumpbin.exe,添加到环境变量中

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dumpbin /exports screenshot.dll

DLL导出类: 优点:导出的类可以被继承,调用层次也清晰,可以保留类的完整特性; 缺点:不能被其它语言调用(包括C语言),封装性并不是太好。

导出函数: 优点:可以被其它语言调用,使用简单,封装性相对较好; 缺点:调用层次不明显,尤其是在导出函数多的情况下,比较混乱,不能出现同名导出函数。

运行库

https://www.microsoft.com/zh-CN/download/details.aspx?id=48145

https://www.microsoft.com/zh-cn/download/details.aspx?id=26999

C#调用DLL方法

项目文件夹下创建DLLCPP文件夹,把screenshot.dll放进来

属性=>生成事件=>生成前事件命令行中添加

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
xcopy /Y /i /e $(ProjectDir)\DLLCPP $(TargetDir)\

页面中调用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[DllImport("screenshot.dll", EntryPoint = "ScreenShot", CallingConvention = CallingConvention.Cdecl)]
public extern static bool ScreenShot(string szSavePath);

[DllImport("screenshot.dll", EntryPoint = "MyBmp2Jpeg", CallingConvention = CallingConvention.Cdecl)]
public extern static int MyBmp2Jpeg(string bmp, string jpeg);

调用方式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ScreenShot("D:\\pic\\2.bmp");
MyBmp2Jpeg("D:\\pic\\2.bmp", "D:\\pic\\2.jpeg");
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-07-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
1 条评论
热度
最新
我滴妈呀讲的太细了 专门登录感谢你一下
我滴妈呀讲的太细了 专门登录感谢你一下
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
单片机拍照_将采集的RGB图像封装为BMP格式保存到SD卡
BMP (Bitmap) 图像格式是一种无损压缩的位图文件格式,最初由微软公司在Windows操作系统中引入,用于存储图像数据。BMP格式的主要优点是它简单易用,且支持多种颜色深度。这种格式不包含任何压缩算法,这意味着图像的质量不会因为保存而损失,但这也导致了文件大小相对较大。
DS小龙哥
2025/05/27
810
单片机拍照_将采集的RGB图像封装为BMP格式保存到SD卡
yuv420格式(微信图片存储路径)
YUV,分为三个分量,“Y”表示明亮度,也就是灰度值;“U”和”V”表示的则是色度,作用是描述影像色彩饱和度,用于指定像素的颜色。YUV主流的采样方式有三种:YUV4:4:4,YUV4:2:2,YUV4:2:0,这里主要介绍下YUV420。
全栈程序员站长
2022/07/28
2.2K0
yuv420格式(微信图片存储路径)
YV12转RGB24的计算转换和bmp(dib)文件的显示保存
最近又接触到图像处理这一块,翻查到一年前自己写的代码http://blog.csdn.net/gongluck93/article/details/52813042,发现有点看不懂了! 所以自己又整理了一波(YV12转RGB24,显示和保存dib): #include "stdafx.h" /******************************************************************* * Copyright(c) 2017 * All rights rese
_gongluck
2018/03/09
1.4K0
libjpeg:实现jpeg内存压缩暨error_exit错误异常处理和个性化参数设置
libjpeg-turbo是与libjpeg接口兼容的一个jpeg编/解码库,其主要的特点就是利用SIMD指令(如X86架构的MMX/SSE/SSE2,ARM架构的NEON)来加速jpeg图像的编/解码,相比被广泛使用的libjpeg,编码和解码性能提高2~4倍左右。 本文介绍的内容适用于libjpeg-turbo和libjpeg(80以上版本) 关于如何用gcc对libjpeg-turbo编译,请参考我之前的一篇的博文《mingw(gcc)编译libjpeg-turbo》
10km
2022/05/07
1.1K0
C语言之图像文件的属性
本项目的目标是编写一个 C 语言程序,能够读取 BMP 格式的图像文件,并提取图像的基本属性,如宽度、高度、颜色深度等。程序需要解析文件格式并提取属性,但不需要对图像进行渲染或处理。
LucianaiB
2025/01/24
990
C语言之图像文件的属性
Retinex图像增强算法代码
http://www.cnblogs.com/sleepwalker/p/3676600.html?utm_source=tuicool http://blog.csdn.net/carson2005
流川疯
2022/05/06
8890
Retinex图像增强算法代码
图像处理基础(六)-libjpeg常用算法
bmp文件转化为bgr数据 void bmpfile_to_bgr(char *bmp_file,BYTE **rgb,int *size,int *w,int *h,int *bit) { FILE *fp = fopen(bmp_file,"rb"); if(fp == NULL) return; BITMAPFILEHEADER bmpheader; BITMAPINFOHEADER bmpinfo; fread(&bmpheader,sizeof(BITMAP
Pulsar-V
2019/03/12
8650
C/C++ 获取PE文件的各种信息
首先感谢cyxvc老哥,他的代码可读性超高,精简有用以理解,我找这方面的资料好久了,这篇文章对我帮助很大。
王 瑞
2022/12/28
8280
C/C++ 获取PE文件的各种信息
Linux小项目-数码相册设计
这是基于Linux系统开发板设计一个小项目-数码相册,在LCD屏上可以显示完成常见的图片显示,翻页、旋转、缩放等功能。
DS小龙哥
2022/05/11
1.5K0
Linux小项目-数码相册设计
Linux应用开发-LCD显示BMP图片
BMP是一种与硬件设备无关的图像文件格式,是Windows环境中交换与图有关的数据的一种标准,在Windows环境中运行的图形图像软件都支持BMP图像格式。BMP格式的图片存放的就是原始的RGB数据,一般没有做压缩,也就是图片的画质是最原始的,也导致BMP图片占用的内存非常大。现在常用的jpg、jpeg格式都是压缩格式,保存的时候通过算法编码压缩,显示的时候再解压成RGB数据渲染显示。
DS小龙哥
2022/05/11
4.3K0
Linux应用开发-LCD显示BMP图片
Linux应用开发【第二章】图像处理应用开发
​ 前言:所有的图像文件,都是一种二进制格式文件,每一个图像文件,都可以通过解析文件中的每一组二进制数的含义来获得文件中的各种信息,如图像高度,宽度,像素位数等等。只是不同的文件格式所代表的二进制数含义不一样罢了。我们可以通过UltraEdit软件打开图像文件并查看里面的二进制数排列。
韦东山
2021/12/15
1.1K0
Linux应用开发【第二章】图像处理应用开发
Linux下采集摄像头的图像再保存为JPG图片存放到本地(YUYV转JPG)
操作系统:ubuntu18.04 X64位 和 嵌入式Linux操作(ARM)
DS小龙哥
2022/01/12
4.6K0
Linux下采集摄像头的图像再保存为JPG图片存放到本地(YUYV转JPG)
使用Jpeglib
/******************************************************************* * Copyright(c) 2017 * All rights reserved. * * 文件名称: Jpeg.cpp * 简要描述: 使用Jpeglib * * 创建日期: 2017-08-14 * 作者: gongluck * 说明: * * 修改日期: * 作者: * 说明: ********************
_gongluck
2018/03/08
1.1K0
荔枝派Zero(全志V3S)驱动开发之RGB LCD屏幕显示jpg图片
由于从上篇博文 “荔枝派Zero(全志V3S)驱动开发之RGB LCD屏幕显示bmp图片” 中只实现了显示 bmp 图片,实际上我们很常用到的图片多数是 jpg 格式图片,因此我们需要折腾一下,实现 jpg 文件的显示。
Gnep@97
2023/08/10
5220
荔枝派Zero(全志V3S)驱动开发之RGB LCD屏幕显示jpg图片
【C】用C语言提取bmp图片像素,并进行K-means聚类分析——容易遇到的问题
关于bmp图片的格式,网上有很多文章,具体可以参考百度百科,也有例子程序。这里只提要注意的问题。 (1)结构体定义问题:首先按照百度百科介绍的定义了结构体,但是编译发现重定义BITMAPFILEHEADER等。其实只要包含了Windows.h,里面的wingdi.h就已经定义了处理bmp的结构体,故不需要自己再重复定义。 (2)读取文件的字节对其问题:要使用#pragma pack (1)来方便读取文件头的结构体,否则结构体的大小会由于字节对齐问题改变。不知是否头文件中已经使用了该宏,在我的代码中注释掉#p
ascii0x03
2018/04/12
2.6K0
【开源程序(C++)】获取bing图片并自动设置为电脑桌面背景
众所周知,bing搜索网站首页每日会更新一张图片,张张漂亮(额,也有一些不合我口味的),特别适合用来做电脑壁纸。
xiaoxi666
2018/10/29
2.1K0
RGB源数据操作: 实现图片放大、缩小
gcc 版本 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC)
DS小龙哥
2022/01/12
2.7K0
RGB源数据操作:  实现图片放大、缩小
Linux应用开发-libjpeg库交叉编译与使用
在开发板上如果想要显示jpeg格式的图片,必须用到libjpeg库,不可能自己去编写jpg的解码代码。
DS小龙哥
2022/05/09
4.1K0
Linux应用开发-libjpeg库交叉编译与使用
C++ OpenCV输出中文
以前的文章《C++ OpenCV视频操作之图像输出文字》介绍了OpenCV中的putText函数可以输出文字,但是这个函数只能输出英文,如果输入的是中文会变为乱码,今天我们就来实现OpenCV输出中文(只在windows环境下)。
Vaccae
2020/11/09
4.5K0
C++ OpenCV输出中文
WinCE平台下BMP转JPG代码备份
  这大概是一年前做的事情了,当时的项目要求在WinCE平台下BMP转JPG,然后自己折腾了好几个月才终于搞定,现在时间过去了快一年了,估计自己今后再也不会碰WinCE相关的东西了吧,而且也准备把相关的学习笔记和代码项目全部删除掉。这些没有经过整理过的东西,放在电脑上也是垃圾,还不如整理一下,放到网上,让有需要的同学借鉴参考一下吧。
用户1170933
2022/05/10
4.2K0
推荐阅读
相关推荐
单片机拍照_将采集的RGB图像封装为BMP格式保存到SD卡
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验