【问题标题】:How do I get files in my own file format to have its own dynamic icon?如何以自己的文件格式获取文件以拥有自己的动态图标?
【发布时间】:2008-09-23 13:06:57
【问题描述】:

我们的应用程序的文件格式类似于 OpenDocument 文件格式(请参阅 http://en.wikipedia.org/wiki/OpenDocument) - 即使用清单文件、缩略图等进行压缩。

我注意到 OpenOffice 文件在 Windows 和 Linux 中都有一个 Open Office 文件的预览图像作为它们的图标。有没有办法为我们的文件实现这一点:即我想要一个基于内部 thumbnail.png 的动态图标?

编辑 1 哇,感谢所有快速回答。 Thumbnailer 看起来非常适合 GNOME 世界。 Windows 我将研究这些链接,谢谢。至于评论问题:以编程方式或通过我们的安装程序。

编辑 2 哦,忘了 Mac。在 Mac 上怎么样? (对不起 Mac 爱好者!)还有关于 OpenOffice 如何处理他们的 IconHandler 东西的任何链接或信息 - 因为我们的会非常相似?

【问题讨论】:

  • 你的意思是编程吗?通过安装程序?还是只是本地盒子上的手动任务?

标签: file icons opendocument


【解决方案1】:

窗口

您需要的是Icon Handler,也称为缩略图处理程序。这是一个写成active x control的例子。

另一个资源是查找Property Handlers,它还应该为您指出在 Windows 中正确处理动态元数据的最新和最好的方法。

这些是 动态 解决方案 - 如果您只需要与所有文件关联的图标,则不需要它们 - 仅当您希望 Windows 资源管理器根据文件中的内容显示图标时才使用它们文件,而不仅仅是扩展名,当文件更改时,图标会更新以反映更改。它也不必是文件本身的图像,缩略图处理程序可以根据文件内容生成任何图像。

属性处理程序会更新其他元数据,例如歌曲或视频长度,因此您可以使用 Windows 资源管理器支持的所有元数据。

关于 MAC 支持,this page 说:“Mac 和 Windows 操作系统有不同的方法来启用这种类型的缩略图,而对于 Mac OS,这种支持在不同版本之间是不一致的,所以它没有没有被 [for Adob​​e InDesign] 追求。”

操作系统

Mac OSX 的图标由Launch Services Database 确定。但是,它指的是由注册应用程序处理的所有文件的静态图标文件(它不是基于扩展名 - 每个文件都附加了元数据,这些元数据决定了它所属的应用程序,尽管当元数据没有时扩展名会给出提示存在,例如从不同的操作系统或文件系统获取文件)

看起来 OSX 中的动态图标功能是由 Finder 提供的,但搜索并没有在这个方向上提供任何简单的指针。由于Finder随着时间的推移不断变化,我可以看到为什么这个目标很难达到......

侏儒

对于 Gnome,您使用 thumbnailer。 (感谢Dorward

这是你编写的一个非常简单的程序,它有 3 个命令行参数:

  • 输入文件名,您使用缩略图描述的文件(或 URI,如果您接受它们)
  • 输出文件名,需要写PNG的地方
  • 大小,一个数字,以像素为单位,描述您应该生成的最大方形图像大小(128 --> 128x128 或更小)

我希望所有系统都这么简单。另一方面,它不支持动画和其他一些由其他系统上更难实现的插件提供的功能。

KDE

我有点不确定,但有一些建议可以帮助您入门。首先是 Konqueror 是文件管理器并显示图标 - 它支持某些内置类型的动态图标,但我不知道这些是硬编码的,还是您可以编写的插件。查看Embedded Components Tutorial 以获得起点。

有一个名为 Plasma 的新(ish?)功能(或计划中的功能......)与图标和图标功能有很大关系。查看this announcmentthis initial implementation

您可能需要深入了解 Konqueror 的源代码,并查看他们如何对文本文件和其他已实现的文件执行此操作。

-亚当

【讨论】:

  • ..这就是为什么你有 4k 代表而我有 81 的原因!那里的深度很大。好答案!
  • 好东西,亚当。非常感谢。添加指向 Gnome 缩略图的链接,我会接受这个答案。
【解决方案2】:

Mac OSX 自 10.5 版起……

…有两种方法:

  1. 您的文档采用标准 OSX 捆绑包格式并具有静态图像 这可以通过创建一个子文件夹 QuickLook 并将 Thumbnail/Preview.png/tiff/jpg 放入其中来完成。

  2. 其他所有内容都需要一个 QuickLook 生成器插件,该插件可以存储在 /Library/QuickLook ~/Library/QuickLook 或 YourApp.app/Contents/Library/QuickLook 文件夹中。

此生成器用于动态创建缩略图和 QuickLook 预览。 XCode 为此提供了一个模板。该模板生成需要实现的 ANSI C 文件。如果您想编写 Object-C 代码,您必须将 GenerateThumbnailForURL.c 和 GeneratePreviewForURL.c 重命名为 GenerateThumbnailForURL.m 和 GeneratePreviewForURL.m(并仔细阅读 Apple 开发文档;))


简单的基于 zip 容器的演示:

您必须将 Cocoa.framework 和 Foundation.framework 添加到您的项目中 在您的 GenerateThumbnailForURL.c 中(这部分是我的想法 - 所以不能保证它开箱即用;)):

#include <Cocoa/Cocoa.h>
#include <Foundation/Foundation.h>

OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize)
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  /* unzip the thumbnail and put it into an NSData object */
  // Create temporary path and writing handle for extraction
  NSString *tmpPath = [NSTemporaryDirectory() stringByAppendingFormat: [NSString stringWithFormat: @"%.0f.%@" , [NSDate timeIntervalSinceReferenceDate] * 1000.0, @"png"]];
  [[NSFileManager defaultManager] createFileAtPath: tmpPath contents: [NSData alloc] attributes:nil];
  NSFileHandle *writingHandle = [NSFileHandle fileHandleForWritingAtPath: tmpPath];


  // Use task to unzip - create command: /usr/bin/unzip -p <pathToFile> <fileToExtract>
  NSTask *unzipTask = [[NSTask alloc] init];
  [unzipTask setLaunchPath: @"/usr/bin/unzip"];

  // -p -> output to StandardOut, added File to extract, nil to terminate Array
  [unzipTask setArguments: [NSArray arrayWithObjects: @"-p", [(NSURL *) url path], @"Thumbnails/thumbnail.png", nil]];

  // redirect standardOut to writingHandle
  [unzipTask setStandardOutput: writingHandle];

  // Unzip - run task
  [unzipTask launch];
  [unzipTask waitUntilExit];

  // Read Image Data and remove File
  NSData *thumbnailData = [NSData dataWithContentsOfFile: tmpPath];
  [[NSFileManager defaultManager] removeFileAtPath: tmpPath handler:nil];


  if ( thumbnailData == nil || [thumbnailData length] == 0 ) {
     // Nothing Found. Don't care.
     [pool release];
     return noErr;
  }

  // That is the Size our image should have - create a dictionary too
  CGSize size = CGSizeMake(256, 256);
  NSDictionary *properties = [NSDictionary dictionaryWithObjectsAndKeys:
      [NSNumber numberWithInt:size.width],kQLPreviewPropertyWidthKey,
      [NSNumber numberWithInt:size.height],kQLPreviewPropertyHeightKey,
      nil];

  // Get CGContext for Thumbnail
  CGContextRef CGContext = QLThumbnailRequestCreateContext(thumbnail, size, TRUE, (CFDictionaryRef)properties);
  if(CGContext) {
     NSGraphicsContext* context = [NSGraphicsContext graphicsContextWithGraphicsPort:(void *)CGContext flipped:size.width > size.height];
     if(context) {
        //These two lines of code are just good safe programming…
       [NSGraphicsContext saveGraphicsState];
       [NSGraphicsContext setCurrentContext:context];

       NSBitmapImageRep *thumbnailBitmap = [NSBitmapImageRep imageRepWithData:thumbnailData];
       [thumbnailBitmap draw];

       //This line sets the context back to what it was when we're done
       [NSGraphicsContext restoreGraphicsState];
    }

    // When we are done with our drawing code QLThumbnailRequestFlushContext() is called to flush the context
    QLThumbnailRequestFlushContext(thumbnail, CGContext);

    // Release the CGContext
    CFRelease(CGContext);
  }

  [pool release];
  return noErr;
}

Info.plist

您也必须修改您的 info.plist 文件 - 当您打开它时,它会预先设置很多字段。它们中的大多数都是不言自明的(或者不必更改),但我必须添加以下结构(复制粘贴应该可以 - 复制文本,进入 plist 编辑器并粘贴。):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
   <dict>
     <key>UTTypeConformsTo</key>
     <array>
       <string>com.pkware.zip-archive</string>
     </array>
     <key>UTTypeDescription</key>
     <string>i-net Crystal-Clear Report File</string>
     <key>UTTypeIconName</key>
     <string>generic</string>
     <key>UTTypeIdentifier</key>
     <string>com.company.product</string>
     <key>UTTypeReferenceURL</key>
     <string>http://your-url.com</string>
     <key>UTTypeTagSpecification</key>
     <dict>
       <key>public.filename-extension</key>
         <array>
           <string>$fileEXT$</string>
         </array>
     </dict>
  </dict>
</array>
</plist>

这将注册您的文件类型 $fileExt$ 并告诉系统您的文件类型是 zipy 格式类型。一个很好的参考,我在这里使用的是QuickLook IPA Plugin from googlecode

【讨论】:

    【解决方案3】:

    在 Windows 中,您需要实现一个图标处理程序。我在很多个月前就做过这个,只要你了解 COM 的基础知识,这并不难。

    见:http://msdn.microsoft.com/en-us/library/bb776857(VS.85).aspx

    【讨论】:

      【解决方案4】:

      对于 Gnome,您使用 thumbnailer

      【讨论】:

        【解决方案5】:

        据我所知,这取决于操作系统,它将基于文件扩展名。

        【讨论】:

          【解决方案6】:

          对于 WINDOWS 试试这个:

          http://www.easydesksoftware.com/news/news12.htm

          【讨论】:

            【解决方案7】:

            可执行文件将文件内的图标(可能是多个)作为“资源”。

            数据文件根据文件关联选择一个图标。

            如果您希望每个文件都有一个自定义图标,那就更难了。您要么需要让操作系统误以为它是可执行文件并将图标作为资源嵌入文件中,要么需要深度链接到操作系统以覆盖默认图标选择例程。

            【讨论】:

              【解决方案8】:

              我认为,“自定义自己的”图标在 Windows 中只能有 PE 文件。文件扩展名的所有其他图标都存储在 Windows 注册表中。

              PE文件的规格可以看An In-Depth Look into the Win32 Portable Executable File FormatPeering Inside the PE: A Tour of the Win32 Portable Executable File Format

              它在其他操作系统中如何工作,我不知道:/。

              【讨论】:

                【解决方案9】:

                我不了解 Linux,但对于 Windows,您可以从这里开始: http://msdn.microsoft.com/en-us/library/bb774614.aspx

                编辑:我认为这个界面适用于缩略图视图中显示的缩略图,而不是图标。很抱歉浪费了您的时间。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-06-15
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-01-30
                  • 2023-03-14
                  • 2011-02-08
                  相关资源
                  最近更新 更多