【C#在资源管理器中显示自定义文件格式的缩略图】

C++版可以参考https://learn.microsoft.com/zh-cn/windows/win32/shell/building-thumbnail-providers
C#版:https://github.com/jkavalik/GcodeThumbnailExtension
需要用到的插件:SharpShell
这里我们以自定义格式".gcode", “.gco"为例:
这里的主入口函数是"GetThumbnailImage”,其他的都是去实现这个接口的

这里我们准备一个通用缩略图,而不是文件内部的的缩略图,先跑通程序,准备通用缩略图图片
【C#在资源管理器中显示自定义文件格式的缩略图】_第1张图片
修改里面的函数ReadThumbnailFromGcode,让它强制指向我们的通用缩略图

     private Image ReadThumbnailFromGcode(StreamReader reader)
        {
            Image image = Image.FromFile(@"C:\Users\tianj\Pictures\cde2d8d4-f4b3-4379-b7b5-0960a82d70ae.png");
            return image;
        }

编译程序

创建bat,内容

ServerRegistrationManager.exe install GcodeThumbnailExtension.dll -codebase

保存后双击运行bat

如果你操作没有错的话,刷新资源管理器后,结果是这样的:
【C#在资源管理器中显示自定义文件格式的缩略图】_第2张图片

那么下一步,就是StreamReader reader解析对应格式里面的缩略图了,源程序是把缩略图以base64字符串存储到自定义格式里,这里就看你怎么解析了

写入自定义图片:
这里不建议用第三方库,有可能会调用失败,推荐是用BinaryReader和BinaryWriter直接写入数据
数据写入的格式:(仅供参考)
【C#在资源管理器中显示自定义文件格式的缩略图】_第3张图片

            var byte1 = System.IO.File.ReadAllBytes(@"C:\Users\tianj\Pictures\Camera Roll\Cbz_Ext_Cover.jpg");
            var byte2 = System.IO.File.ReadAllBytes(@"C:\Users\tianj\Pictures\Camera Roll\Cbz_Ext_Chapter.json");
            var byte3 = System.IO.File.ReadAllBytes(@"C:\Users\tianj\Pictures\Camera Roll\aaa.zip");
            //String strbaser64 = Convert.ToBase64String(byte2);
            //var len = byte2.Length;
            using (FileStream fileStream = new FileStream(@"demott.milkl", FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                using (System.IO.BinaryWriter binaryWriter = new BinaryWriter(fileStream))
                {
                    binaryWriter.Write(byte1.Length);

                    var jsonLenBytes= BitConverter.GetBytes(byte2.Length);
                    var zipLenBytes= BitConverter.GetBytes(byte3.Length);
                    Console.WriteLine("zipLenBytes:"+ zipLenBytes.Length);
                    //x len
                    //binaryWriter.Write(byte2.Length+ byte3.Length+ jsonLenBytes.Length+ zipLenBytes.Length);
                    binaryWriter.Write(0);
                    binaryWriter.Write(byte1);

                    //x
                    binaryWriter.Write(byte2.Length);
                    binaryWriter.Write(byte2);

                    binaryWriter.Write(byte3.Length);
                    binaryWriter.Write(byte3);


                    //binaryWriter.Write(byte3.Length);
                    //binaryWriter.Write(byte3);
                }
            }

解码

 using (FileStream fileStream = new FileStream(@"demott.milkl", FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                using (System.IO.BinaryReader binaryWriter = new BinaryReader(fileStream))
                {
                   
                  
                   
                    //Console.WriteLine("--img:"+ size1);
                    //Console.WriteLine("--json:"+ size2);
                    //Console.WriteLine("--7z:"+ size3);
                    int size1 = binaryWriter.ReadInt32();
                    int sizex = binaryWriter.ReadInt32();
                    var imageBytes = binaryWriter.ReadBytes(size1);

                    int size2 = binaryWriter.ReadInt32();
                    var jsonBytes = binaryWriter.ReadBytes(size2);

                    int size3 = binaryWriter.ReadInt32();
                    var zipBytes = binaryWriter.ReadBytes(size3);


                    System.IO.File.WriteAllBytes("zip.zip", zipBytes);
                    System.IO.File.WriteAllBytes("zip.jpg", imageBytes);
                    System.IO.File.WriteAllBytes("zip.json", jsonBytes);
                }
            }

最终,再次修改上面的ReadThumbnailFromGcode函数为,编译即可

  private Image ReadThumbnailFromGcode(StreamReader reader)
        {
            Image result = null;
            reader.BaseStream.Position = 0L;
            using (BinaryReader binaryReader = new BinaryReader(reader.BaseStream))
            {
                int size1 = binaryReader.ReadInt32();
                int size0 = binaryReader.ReadInt32();
                 result = Image.FromStream(new MemoryStream(binaryReader.ReadBytes(size1)));
           }
            return result;
        }

这个插入一个0不知道为什么,不插入好像不行,懒得尝试了

最终的效果是:
【C#在资源管理器中显示自定义文件格式的缩略图】_第4张图片
我定义的milkl格式可以正常显示二进制包里的图片数据了!

你可能感兴趣的:(工具,图片处理,c#,.net)