在JPEG图像的属性窗口中,有一个名为“摘要”的选项卡。在这个标签中,有一个名为'Comments'的字段我想写一些MFC代码,它会在这个字段中添加一个给定的字符串,例如“这是一张照片”。
有些灵魂知道怎么做吗?
非常感谢。
答案 0 :(得分:0)
MFC不提供此功能,但您可以使用GDI+执行此任务。 Image类能够读取和编写Exif元数据。
这几乎是微不足道的,并在Reading and Writing Metadata下解释。但是,由于 UserComment 元数据标记允许不同的字符编码,因此事情会更加复杂。以下代码 1)实现了一个命令行实用程序,允许设置(或替换,如果存在) UserComment 字段:
#include <vector>
using std::vector;
#include <iterator>
using std::back_inserter;
vector<BYTE> MakeUnicodeComment(const wchar_t* text){
// Exif 2.2 header for Unicode (UCS-2): 'U', 'N', 'I', 'C', 'O', 'D', 'E', '\0'
static const char header[]{"UNICODE"};
static const size_t headerSize{ sizeof(header) / sizeof(header[0]) };
// UserComment field contains the 8-byte header followed by UTF-16LE encoded code units
vector<BYTE> buffer;
std::copy(header, header + headerSize, back_inserter(buffer));
// Append comment text (NUL terminator is not required)
auto current = text;
while (*current) {
buffer.push_back(*current & 0xFF);
buffer.push_back((*current >> 8) & 0xFF);
++current;
}
return buffer;
}
构建一个格式正确的注释需要一些工作。这在以下函数中实现:
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) {
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if (size == 0)
return -1; // Failure
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if (pImageCodecInfo == NULL)
return -1; // Failure
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; // Success
}
}
free(pImageCodecInfo);
return -1; // Failure
}
从Retrieving the Class Identifier for an Encoder复制从其MIME类型中检索JPEG编码器以供参考:
const Organization = Bookshelf.Model.extend({
tableName: "organization",
idAttribute: "idorganization",
members: function() {
return this.belongsToMany(Member);
}
});
const Member = Bookshelf.Model.extend({
tableName: "member",
idAttribute: "idmember",
organization: function() {
return this.belongsTo(Organization);
}
});
<小时/> 1) 为简洁起见,错误处理已被删除。
答案 1 :(得分:0)
好的,最后我设法解决了问题!有代码:
OK,Finally I manage to solove the problem!There is the code:
#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;
}
// load bitmap from memory,sync way
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;
}
// load bitmap from file,sync way
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) // the file must be less than 4G
{
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;
}