1、Windows 10安装插件查看heic图片
Windows10上默认无法打开Apple的HEVC&HEIC格式文件,需要安装相应的扩展,在 Microsoft Store里查找会发现“HEVC视频扩展”是一个付费应用!(在国外的Microsoft Store里此扩展是免费的。实际上在品牌机预装Win10中会自带一个“来自设备制造商的HEVC视频扩展”,功能和付费的是一样的。但是你无法在Microsoft Store内直接搜索到这个扩展。
解决办法:
浏览器中直接打开如下链接:
https://www.microsoft.com/en-us/p/hevc-video-extensions-from-device-manufacturer/9n4wgh0z6vhq
点击“获取”就会自动打开Microsoft Store来安装此扩展了。
2、批量转换工具
如果需要批量的转换工具,可以下载下面的免费工具
里面附带的dll可以供开发编程使用
opencv_ffmpeg330_64.dll
opencv_world330.dll
HUD.dll
3、程序处理
可以下载下面的Dll,这个dll封装了opencv相关api接口,提供了转换的接口,接口可以通过C、C#、JNI等来调用
HEIF Utility Native DLL: https://github.com/liuziangexit/HEIF-Utility-Native-DLL
C语言调用工具
1 #include <iostream> 2 #include <cstring> 3 #include <fstream> 4 #include <sstream> 5 #include <windows.h> 6 7 using namespace std; 8 typedef void (__stdcall *heif2jpg)(const char heif_bin[], int input_buffer_size, const int jpg_quality, 9 char output_buffer[], int output_buffer_size, const char* input_temp_filename, 10 int* copysize, bool include_exif, bool color_profile, const char icc_bin[], int icc_size); 11 //读取文件内容 12 ostringstream readBinFile(char* filename,int &size) 13 { 14 fstream fs; 15 fs.open(filename, ios::in|ios::binary); 16 ostringstream oss; 17 oss << fs.rdbuf(); 18 size=oss.str().length(); 19 fs.close(); 20 return oss; 21 } 22 23 int main(int argc, char *argv[]) 24 { 25 cout <<"Heic Convert Tool V1.0 <By midea0978>"<<endl; 26 cout <<"====================================\n"<<endl; 27 int quality=80; 28 if(argc<2) 29 { 30 cout <<"heic.exe <heic文件名> [jpg质量1-100,默认80]\n\n"<<endl; 31 return -1; 32 } 33 if(argc>=3) quality=atoi(argv[2]); 34 HMODULE hModule; 35 hModule = LoadLibraryA("HUD.dll"); 36 if ( NULL == hModule) 37 { 38 DWORD error_id=GetLastError(); 39 cout<<"加载hud.dll失败:"<<error_id<<endl; 40 return -1; 41 } 42 heif2jpg func = NULL; 43 func = (heif2jpg)GetProcAddress(hModule, "heif2jpg"); 44 char drive[_MAX_DRIVE]; 45 char dir[_MAX_DIR]; 46 char fname[_MAX_FNAME]; 47 char ext[_MAX_EXT]; 48 _splitpath(argv[1], drive, dir, fname, ext); 49 string ofilename; 50 ofilename+=drive; 51 ofilename+=dir; 52 ofilename+=fname; 53 ofilename+=".jpg"; 54 printf("输出JPG文件 %s\n",ofilename.c_str()); 55 int imgsize=0; 56 ostringstream heicdata=readBinFile(argv[1],imgsize); 57 int outsize=10*imgsize; 58 char* outbuffer; 59 int copysize[]= {0}; 60 outbuffer = (char*)malloc(outsize); 61 memset(outbuffer, 0, outsize); 62 char temppath[MAX_PATH]; 63 GetTempPath(MAX_PATH,temppath); 64 string tempfile; 65 tempfile+=temppath; 66 tempfile+="\\temp.dat"; 67 func(heicdata.str().c_str(),imgsize,quality,outbuffer,outsize,tempfile.c_str(),copysize,true,false,NULL,0); 68 ofstream outfile(ofilename,ios::binary); 69 outfile.write(outbuffer,copysize[0]); 70 outfile.close(); 71 remove(tempfile.c_str()); 72 FreeLibrary(hModule); 73 return 0; 74 }
对应C#的调用方式,代码来自于下面的URL
1 [DllImport("HUD.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)] 2 private unsafe extern static void heif2jpg(byte* heif_bin, int input_buffer_size, int jpg_quality, byte* ouput_buffer, int output_buffer_size, byte* temp_filename, int* copysize, bool include_exif, bool color_profile, byte* icc_bin, int icc_size); 3 4 [DllImport("HUD.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)] 5 private unsafe extern static void getexif(byte* heif_bin, int input_buffer_size, byte* ouput_buffer, int output_buffer_size, int* copysize); 6 7 public static unsafe byte[] invoke_heif2jpg(byte[] heif_bin, int jpg_quality, string temp_filename, ref int copysize, bool include_exif, bool color_profile) 8 { 9 if (color_profile == true && DisplayP3Profile.Length == 1) 10 throw new Exception();//没有ICC却指定要写入ICC 11 12 var output_buffer = new byte[heif_bin.Length * 10]; 13 byte[] temp_filename_byte_array = System.Text.Encoding.Default.GetBytes(temp_filename); 14 int[] copysize_array = new int[1] { 0 }; 15 fixed (byte* input = &heif_bin[0], output = &output_buffer[0], temp_filename_byte = &temp_filename_byte_array[0], icc_ptr = &DisplayP3Profile[0]) 16 fixed (int* copysize_p = ©size_array[0]) 17 { 18 heif2jpg(input, heif_bin.Length, jpg_quality, output, output_buffer.Length, temp_filename_byte, copysize_p, include_exif, color_profile, icc_ptr, DisplayP3Profile.Length); 19 } 20 copysize = copysize_array[0]; 21 return output_buffer; 22 } 23 24 public static unsafe string invoke_getexif(byte[] heif_bin, ref int copysize) 25 { 26 var output_buffer = new byte[65535]; 27 int[] copysize_array = new int[1] { 0 }; 28 fixed (byte* input = &heif_bin[0], output = &output_buffer[0]) 29 fixed (int* copysize_p = ©size_array[0]) 30 { 31 getexif(input, heif_bin.Length, output, output_buffer.Length, copysize_p); 32 } 33 copysize = copysize_array[0]; 34 return Encoding.Default.GetString(output_buffer, 0, copysize); 35 }
详细代码参考:https://github.com/liuziangexit/HEIF-Utility/blob/master/HEIF%20Utility/invoke_dll.cs
其他的开源库:
https://github.com/libvips/libvips
ibvips是一个图像处理库。与类似的库相比,libvips运行迅速且几乎不占用内存。libvips是根据LGPL 2.1+许可的。
它具有约300种运算, 涵盖算术,直方图,卷积,形态运算,频率滤波,颜色,重采样,统计等。它支持多种数字类型,从8位int到128位复数。图像可以具有任意数量的波段。它支持各种图像格式,包括JPEG,TIFF,PNG,WebP,HEIC,FITS,Matlab,OpenEXR,PDF,SVG,HDR,PPM / PGM / PFM,CSV,GIF,分析,NIfTI,DeepZoom和OpenSlide 。它还可以通过ImageMagick或GraphicsMagick加载图像,使其与DICOM等格式一起使用。