• MFC读写EXIF信息,图片非占用


    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.
    ");
        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+自己提供的,如果需要修改其他项目,跟到原始文件中,有一个长长的定义,从中选择自己需要的项目就可以。这个过程可能是需要查阅一些文件和进行对比的。
    感谢阅读至此,希望有所收获。
     
  • 相关阅读:
    HTTP Status 500
    HTTP Status 500
    HTTP Status 500
    测试错误ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.问题的解决
    页面报错误:HTTP Status 500
    eclipse怎么设置在新建JSP文件的编码为UTF-8?
    linux 开启oracle监听
    linux 修改环境变量
    linux 修改oracle的字符集
    Cannot change version of project facet Dynamic Web Module to 2.5
  • 原文地址:https://www.cnblogs.com/jsxyhelu/p/6336428.html
Copyright © 2020-2023  润新知