我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C++中图片类型的识别与转换详解方法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C++中图片类型的识别与转换详解方法

1、图片类型的识别

一般情况下,不同类型的图片文件都会有其对应的后缀名,比如.jpg、.bmp、.jpg等。但仅仅通过后缀名,是没法判别文件是不是图片以及图片文件真实类型,必须通过文件内容的起始标记字段才能判断出来。

每种图片文件的类型标识字段存储于文件内容开始的几个字节,读出这几个字节就能判断出图片类型了。下面给出常见的图片类型的判断代码。

以下代码都是调用_tfopen(支持Unicode)打开文件,调用fread读出文件中的类型标记数据。注意,打开文件时必须设置 b - 二进制参数,如果不设置,调用fread时可能读不出指定字节数的内容!

1.1、bmp图片


BOOL32 IsBmpFile( LPCTSTR lpStrFilePath )
{
	FILE* pFile = _tfopen( lpStrFilePath, _T("rb") );
	if ( pFile == NULL )
	{
		return FALSE;
	}
 
	char szData[2] = {0};
	int nReadNum = fread( szData, sizeof(char), 2, pFile );
	if ( nReadNum < 2 )
	{
		fclose( pFile );
		return FALSE;
	}
 
	fclose( pFile );
 
	// bmp: 0x42, 0x4d
	unsigned char szBmpFlag = { 0x42, 0x4d };
	if ( !memcmp( szBmpFlag, szData, 2 ) )
	{		
		return TRUE;
	}	
 
	return FALSE;
}

1.2、jpg图片


BOOL32 IsJpgFile( LPCTSTR lpStrFilePath )
{
	FILE* pFile = _tfopen( lpStrFilePath, _T("rb") );
	if ( pFile == NULL )
	{
		return FALSE;
	}
 
	char szData[2] = {0};
	int nReadNum = fread( szData, sizeof(char), 2, pFile );
	if ( nReadNum < 2 )
	{
		fclose( pFile );
		return FALSE;
	}
 
	fclose( pFile );
	
	// jpg: 0xFF, 0xD8
	unsigned char szJpgFlag[] = { 0xFF, 0xD8 };
	if ( !memcmp( szJpgFlag, szData, 2 ) )
	{		
		return TRUE;
	}	
 
	return FALSE;
}

1.3、jpg图片


BOOL32 IsPngFile( LPCTSTR lpStrFilePath )
{
	FILE* pFile = _tfopen( lpStrFilePath, _T("rb") );
	if ( pFile == NULL )
	{
		return FALSE;
	}
 
	char szData[8] = {0};
	int nReadNum = fread( szData, sizeof(char), 8, pFile );
	if ( nReadNum < 8 )
	{
		fclose( pFile );
		return FALSE;
	}
 
	fclose( pFile );
 
	// png: 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A 
	unsigned char szPngFlag[] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };
	if ( !memcmp( szPngFlag, szData, 8 ) )
	{		
		return TRUE;
	}	
 
	return FALSE;
}

1.4、gif图片


BOOL32 IsGifFile( LPCTSTR lpStrFilePath )
{
    FILE* pFile = _tfopen( lpStrFilePath, _T("rb") );
	if ( pFile == NULL )
	{
		return FALSE;
	}
 
	char szData[6+1] = {0};
	int nReadNum = fread( szData, sizeof(char), 6, pFile );
	if ( nReadNum < 6 )
	{
		fclose( pFile );
		return FALSE;
	}
 
    fclose(pFile);
 
	// 使用字符串判断更直观
	if ( strcmp( szData, "GIF89a" ) == 0 || strcmp( szData, "GIF87a" ) == 0 )
	{
		return TRUE;
	}
 
	return FALSE;
}

1.5、tiff图片


BOOL32 IsTiffFile( LPCTSTR lpStrFilePath )
{
	FILE* pFile = _tfopen( lpStrFilePath, _T("rb") );
	if ( pFile == NULL )
	{
		return FALSE;
	}
 
	char szData[4] = {0};
	int nReadNum = fread( szData, sizeof(char), 4, pFile );
	if ( nReadNum < 4 )
	{
		fclose( pFile );
		return FALSE;
	}
 
	fclose( pFile );
 
	// jpg: 0x49, 0x49, 0x2A, 0x00
	unsigned char szTiffFlag[] = { 0x49, 0x49, 0x2A, 0x00 };
	if ( !memcmp( szTiffFlag, szData, 2 ) )
	{		
		return TRUE;
	}	
 
	return FALSE;
}

1.6、使用CreateFile和ReadFile API函数读取内容

上面是使用fopen和fread读取文件中的内容的,下面给出调用CreateFile和ReadFile API函数实现的代码:


BOOL32 IsJpgFile( LPCTSTR lpStrFilePath )
{
        HANDLE hFile = ::CreateFile(lpStrFilePath, GENERIC_READ, FILE_SHARE_READ, NULL,
                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile == INVALID_HANDLE_VALUE)
        {
                return FALSE;
        }
 
        unsigned char szData[4] = { 0 };
 
        DWORD dwReadNum;
        if (!::ReadFile((HANDLE)hFile, szData, 4, &dwReadNum, NULL))
        {
                CloseHandle(hFile);
                return FALSE;
        }
 
        if ( dwReadNum< 4 )
        {
                CloseHandle(hFile);
                return FALSE;
        }        
 
        CloseHandle(hFile);
 
        unsigned char szJpgFlag[] = { 0xFF, 0xD8 };
 
        // 0xFF,0xD8
        if ( !memcmp( szJpgFlag, szData, 2 ) )
        {                
                return TRUE;
        }       
 
 
        return FALSE;
}

2、图片之间的相互转换

有时我们需要进行不同图片类型之间的相互转换,比如将占用较大存储空间的bmp图片转换成jpg或者jpg图片。可以选择使用GDI+类实现不同图片类型之间的转换。在使用GDI+之前,要先初始化GDI+库:


ULONG_PTR m_gdiplusToken;
	
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
Gdiplus::GdiplusStartup( &m_gdiplusToken, &gdiplusStartupInput, NULL );

在退出程序时,要关闭GDI+库:


Gdiplus::GdiplusShutdown( m_gdiplusToken );

实现图片类型之间相互转换的代码如下:


// 根据目标文件的后缀确定要转换成的目标文件类型
BOOL32 SaveImgFileToAnotherType( const CString& strclass="lazy" data-srcFile, const CString& strDstFile )
{
	// 使用CImage实现不同格式图片文件的转换
	if ( strDstFile.IsEmpty() )
	{
		return FALSE;
	}
 
	CImage img;
	HRESULT hResult = img.Load( strclass="lazy" data-srcFile ); // 加载源图片文件
	if ( hResult != S_OK )
	{
		return FALSE;
	}
 
	GUID guidFileType = Gdiplus::ImageFormatPNG; // 默认保存为png图片
	CString strExt;
	s32 nIndex = strDstFile.ReverseFind( _T('.') );
	if ( nIndex != -1 )
	{
		strExt = strDstFile.Right( strDstFile.GetLength() - nIndex - 1 );
		if ( strExt == _T("png") )
		{
			guidFileType = Gdiplus::ImageFormatPNG;
		}
		else if ( strExt == _T("jpg"))
		{
			guidFileType = Gdiplus::ImageFormatJPEG;
		}
		else if ( strExt == _T("bmp") )
		{
			guidFileType = Gdiplus::ImageFormatBMP;
		}
		else if ( strExt == _T("gif") )
		{
			guidFileType = Gdiplus::ImageFormatGIF;
		}
		else
		{
			guidFileType = Gdiplus::ImageFormatPNG;
		}
	}
 
	hResult = img.Save( strDstFile, guidFileType ); // 保存为目标文件
	if ( hResult != S_OK )
	{
		return FALSE;
	}
 
	return TRUE;
}

以上就是C++中图片类型的识别与转换详解方法的详细内容,更多关于C++ 图片类型转换的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C++中图片类型的识别与转换详解方法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

详解C++中四种类型的转换

这篇文章主要是想和大家一起聊聊来C++中的四种类型转换 :const_cast、static_cast、reinterpret_cast和dynamic_cast,感兴趣的可以了解一下
2022-12-08

C语言隐式类型转换与强制类型转换的方法是什么

本篇内容主要讲解“C语言隐式类型转换与强制类型转换的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C语言隐式类型转换与强制类型转换的方法是什么”吧!类型转换数据有不同的类型,不同类型数
2023-06-25

C++中类型转换的方法有哪些

这篇文章主要介绍“C++中类型转换的方法有哪些”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C++中类型转换的方法有哪些”文章能帮助大家解决问题。1. C语言中的类型转换在C语言中,如果赋值运算符左
2023-07-05

C++中的强制类型转换操作详解

C++中提供了四种强制类型转换技术:static_cast、dynamic_cast、reinterpret_cast和const_cast。这些技术能够在需要时将一种类型转换为另一种类型,但需要注意它们的适用条件和安全性。程序员需要根据具体情况选择合适的强制类型转换方式,以确保程序的正确性和可靠性
2023-05-17

PHP中int类型转换为字节的方法详解

PHP中int类型转换为字节的方法详解在PHP中,我们经常需要将整数类型(int)转换为字节(Byte)类型,比如在处理网络数据传输、文件处理或者加密算法等场景中。本文将详细介绍如何将int类型转换为字节类型,以及提供具体的代码示例。1
PHP中int类型转换为字节的方法详解
2024-03-06

C++中4种类型转换的方法分享

这篇文章主要为大家详细介绍了C++中4种类型转换的方法,文中的示例代码讲解详细,对我们学习C++有一定的帮助,感兴趣的可以了解一下
2023-05-14

C++中四种类型转换的方法是什么

这篇文章主要介绍了C++中四种类型转换的方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++中四种类型转换的方法是什么文章都会有所收获,下面我们一起来看看吧。一、隐式类型转换和显示类型转换当等号两边的
2023-07-05

JAVA11中图片与BASE64相互转换的实现方法

这篇文章主要介绍了JAVA11中图片与BASE64相互转换的实现方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。常用的java框架有哪些1.SpringMVC,Spring
2023-06-14

C语言中强制类型转换的常见方法

强制类型转换是一种将一个数据类型转换为另一个数据类型的方法,这篇文章主要为大家整理了C语言中强制类型转换的方法,需要的可以参考一下
2023-05-20

C++中常见的数据类型转换问题及解决方法

C++ 中常见的数据类型转换问题及解决方法引言:在 C++ 编程中,经常会遇到不同数据类型之间的转换问题。正确地进行数据类型转换是保证程序正确性和性能的关键之一。本文将介绍一些常见的数据类型转换问题,并提供相应的解决方法和具体的代码示例。一
2023-10-22

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录