MFC读写EXIF信息

读取有类库可以直接调用,网络上有直接可以用的;但是写Exif的资料非常少,我花了一点时间研究收集,终于成功。
将相关的资料共享。主要是借助gdi+,需要注意的地方很多
 
// ConsoleApplication2.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;
#pragma comment(lib, "gdiplus.lib")
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num= 0;
UINT size= 0;
ImageCodecInfo* pImageCodecInfo= NULL;
GetImageEncodersSize(&num, &size);
if(size== 0)
{
return -1;
}
pImageCodecInfo= (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo== NULL)
{
return -1;
}
GetImageEncoders(num, size, pImageCodecInfo);
for(UINT j=0; j< num; ++j)
{
if(wcscmp(pImageCodecInfo[j].MimeType, format)== 0)
{
*pClsid= pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j;
}
}
free(pImageCodecInfo);
return -1;
}
// 从内存加载图片,失败返回NULL
Bitmap* LoadBitmapFromMemory(const void* memory, DWORD size)
{
Bitmap* bmp = NULL;
IStream* stream = NULL;
if (CreateStreamOnHGlobal(NULL, TRUE, &stream) == S_OK)
{
ULARGE_INTEGER uli;
uli.QuadPart = size;
stream->SetSize(uli);
if (stream->Write(memory, size, NULL) == S_OK)
bmp = new Bitmap(stream);
stream->Release();
}
return bmp;
}
// 从文件加载图片,不独占文件,失败返回NULL
Bitmap* LoadBitmapFromFile(const TCHAR* file_name)
{
Bitmap* bmp = NULL;
HANDLE file_handle = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle != INVALID_HANDLE_VALUE)
{
DWORD temp = 0;
DWORD file_size = GetFileSize(file_handle, &temp);
if (file_size && !temp) // 不处理大于4G的文件
{
// 将图片文件读到内存后,再从内存创建Bitmap
unsigned char* buffer = new unsigned char[file_size];
if (ReadFile(file_handle, buffer, file_size, &temp, NULL))
bmp = LoadBitmapFromMemory(buffer, temp);
delete [] buffer;
}
CloseHandle(file_handle);
}
return bmp;
}
int _tmain(int argc, _TCHAR* argv[])
{
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Status stat;
CLSID clsid;
char propertyValue[] = "Fake Photograph";
Bitmap* bitmap = LoadBitmapFromFile(L"E:/sandbox/stone.jpg");
PropertyItem* propertyItem = new PropertyItem;
// Get the CLSID of the JPEG encoder.
GetEncoderClsid(L"image/jpeg", &clsid);
propertyItem->id = PropertyTagCopyright;
propertyItem->length = 16; // string length including NULL terminator
propertyItem->type = PropertyTagTypeASCII;
propertyItem->value = propertyValue;
bitmap->SetPropertyItem(propertyItem); stat = bitmap->Save(L"E:/sandbox/stone.jpg", &clsid, NULL);
if(stat == Ok)
printf("FakePhoto2.jpg saved successfully.\n");
delete propertyItem;
delete bitmap;
GdiplusShutdown(gdiplusToken);
return 0;
return 0;
}
这段console代码共4个函数。main函数,GetEncoderClsid LoadBitmapFromMemory和LoadBitmapFromFile函数。其中GetEncoderClsid 函数是GDI+自己用于获得图片格式的。之所以要使用非占用的方式打开图片,是因为写入EXIF的信息也是图片自己信息的一部分,如果采用直接打开的方法,那么原始资源被占用,造成EXIF信息写不进去。
main函数中,就是主要过程。采用GDI+写入SetPropertyItem的方法进行写入。函数中E:/sandbox/stone.jpg是文件名,按照自己需要修改。
在本例中,我改写的EXIF项目PropertyTagCopyright这个是GDI+自己提供的,如果需要修改其他项目,跟到原始文件中,有一个长长的定义,从中选择自己需要的项目就可以。这个过程可能是需要查阅一些文件和进行对比的。
感谢阅读至此,希望有所收获。
 

MFC读写EXIF信息,图片非占用的更多相关文章

  1. 图片Exif信息

    Exif文件格式简述链接:https://www.zhihu.com/question/23727439/answer/25467748 可交换图像文件常被简称为Exif(Exchangeable i ...

  2. 以最省内存的方式把大图片加载到内存及获取Exif信息和获取屏幕高度和宽度的新方法

    我们在加载图片时经常会遇到内存溢出的问题,图片太大,我们加载图片时,一般都是用的如下一般方法(加载本地图片): /** * 不作处理,去加载图片的方法,碰到比较大的图片会内存溢出 */ private ...

  3. 用C#读取相片(JPG图片)的EXIF信息的方法

    引言:EXIF,是英文Exchangeable Image File{}#endregion#region 数据转换结构/// summary>/// 转换数据结构/// /summary> ...

  4. 七牛--关于图片上传方向不统一的问题--主要关于图片EXIF信息中旋转参数Orientation的理解

    [图片引用方向纠正]直接在图片后面添加 ?imageMogr/auto-orient eg:http://data.upfitapp.com/data/2016/10/18/1629114767606 ...

  5. 图片Exif 信息中Orientation的理解和对此的处理

    这个问题是在用七牛上传图片后获取宽高时发现的,一张图片,用图片浏览器打开始终是竖图,但是查看属性或者用七牛获取宽高,却发现宽大于高,也就是在属性中这是个横图.这样导致客户端用该宽高来展示图片会出现问题 ...

  6. Android 获取图片exif信息

    使用android api读取图片的exif信息 布局代码: <LinearLayout xmlns:android="http://schemas.android.com/apk/r ...

  7. 七牛:关于图片 EXIF 信息中旋转参数 Orientation 的理解

    EXIF(Exchangeable Image File)是 “可交换图像文件” 的缩写,当中包含了专门为数码相机的照片而定制的元数据,可以记录数码照片的拍摄参数.缩略图及其他属性信息,简单来说,Ex ...

  8. IOS: 使用imageIO获取和修改图片的exif信息

    使用imageIO获取和修改图片的exif信息 一幅图片除了包含我们能看见的像素信息,背后还包含了拍摄时间,光圈大小,曝光等信息.UIImage类将这些细节信息都隐藏了起来,只提供我们关心的图片尺寸, ...

  9. Android 图片Exif信息相关的获取与修改

    1 Exif是什么 Exif是一种图像文件格式,它的数据存储于JPEG格式是完全相同的,实际上Exif格式就是JPEG格式头插入了 数码照片的信息,包括拍摄的光圈.快门.平衡白.ISO.焦距.日期时间 ...

随机推荐

  1. centos7 ubuntu14 添加sudo 权限 ,禁用每次sudo 需要输入密码

    安装完centos7后,默认没有启用sudo,首先应该是对sudo进行设置.sudo的作用就是使当前非root用户在使用没有权限的命令 时,直接在命令前加入sudo,在输入自己当前用户的密码就可以完成 ...

  2. Neutron SDN 手动实现手册

    安装架构介绍 本文旨在通过自己搭建类似neutron (openvswitch + gre) 实现SDN 的环境,学习了解其工作原理,模拟核心原理,比如:同一租户自定义网络 instance 互通,手 ...

  3. jQuery中的ajax用法案例

    什么是 AJAX? AJAX = 异步 JavaScript 和 XML(Asynchronous JavaScript and XML). 简短地说,在不重载整个网页的情况下,AJAX 通过后台加载 ...

  4. window自带字体

    一.在默认情况下, Windows 默认提供下列字体: Windows 95/98/98SE 宋体.黑体.楷体_GB2312.仿宋_GB2312 Windows XP/2000/2003/ME/NT ...

  5. postgresql数据库中对重复数据的处理

    我们在使用postgresql数据库的时候,如果一张数据表在未做任何约束的情况下,很可能会出现几条完全一样的数据,即重复数据.如下图所示: 那么如果我们要删除其中的2条该怎么办呢?第一种我们可以清空表 ...

  6. SHTML 教程

    什么是 SHTML 使用SSI(Server Side Include)的html文件扩展名,SSI(Server Side Include),通常称为“服务器端嵌入”或者叫“服务器端包含”,是一种类 ...

  7. python webdriver中对不同下拉框通过文本值的选择

    在自动化中python对下拉框的处理网上相对实例比较少,其它前辈写的教程中对下拉也仅仅是相对与教程来说的,比如下面: m=driver.find_element_by_id("Shippin ...

  8. Android dialog 全屏

    Android中让Dialog全屏: 一.在style中定义样式: <?xml version="1.0" encoding="utf-8"?> & ...

  9. CentOS6.8系统安装Oracle11g

    1.官网上下载 软件安装包: linux.x64_11gR2_database_1of2.zip linux.x64_11gR2_database_2of2.zip 解压后: 生成文件夹: datab ...

  10. javascript飞机大战-----008积分

    /* 创建敌机: */ function Enemy(blood,speed,imgs,scroe){ //敌机left this.left = 0; //敌机top this.top = 0; // ...