Apply a thumbnail

Asked

Viewed 80 times

0

How to create any file and in it make Windows Explorer recognize a thumbnail in that file, without modifying or changing it.

Example:

In an archive .PNG the file is not modified and Windows Explore automatically generates a thumbnail.

This also happens in Microsoft Office 2010 files etc.

So how would this be done in C# ?

  • Do you want to create a file in a format that is recognized by these software? Or want to make these software recognize a file format of yours?

1 answer

1


It’s not hard to do, thanks to Sharpshell, which can be downloaded into NUGET. I had to do this for a project a while ago. I used a Code Project article. I will give a brief explanation, but on the site you find a complete explanation (in English) and the link to download the example.

http://www.codeproject.com/Articles/563114/NET-Shell-Extensions-Shell-Thumbnail-Handlers

Basically what you should do is create a COM component. This component, will be registered in windows, and the explorer can use it to render your thumbnails.

Create a new project in c#, and add references to System.Windows.Forms and System.Drawing. Open the Package Manager Console and type Install-Package SharpShell. With all references linked to the project, create a new class and copy the example below. Remembering that all this code was taken from the codeproject article.

using SharpShell.Attributes;
using SharpShell.SharpThumbnailHandler;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace TxtThumbnailHandler
{
    /// <summary>
    /// The TxtThumbnailHandler is a ThumbnailHandler for text files.
    /// </summary>
    [ComVisible(true)] //Torna ele um componente "visível" para a COM
    [COMServerAssociation(AssociationType.FileExtension, ".txt")] // Associa este coponente ao tipo de associação de Extensão de Arquivos, e informa que o tipo de arquivo é neste caso, o txt.
    public class TxtThumbnailHandler : SharpThumbnailHandler
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="TxtThumbnailHandler"/> class.
        /// </summary>
        public TxtThumbnailHandler()
        {
            //  Create our lazy objects.
            lazyThumbnailFont = new Lazy<Font>(() => new Font("Courier New", 12f));
            lazyThumbnailTextBrush = new Lazy<Brush>(() => new SolidBrush(Color.Black));
        }

        /// <summary>
        /// Gets the thumbnail image.
        /// </summary>
        /// <param name="width">The width of the image that should be returned.</param>
        /// <returns>
        /// The image for the thumbnail.
        /// </returns>
        protected override Bitmap GetThumbnailImage(uint width)
        {
            //  Tenta abrir uma stream com o StreamReader.
            try
            {
                using (var reader = new StreamReader(SelectedItemStream))
                {
                    //  Read up to ten lines of text.
                    var previewLines = new List<string>();
                    for (int i = 0; i < 10; i++)
                    {
                        var line = reader.ReadLine();
                        if (line == null)
                            break;
                        previewLines.Add(line);
                    }

                    //  Chama a função que Realiza a geração do thumbnail.
                    return CreateThumbnailForText(previewLines, width);
                }
            }
            catch (Exception exception)
            {
               // Faz algo, tipo gravar num log
                return null;
            }
        }

        /// <summary>
        /// Creates the thumbnail for text, using the provided preview lines.
        /// </summary>
        /// <param name="previewLines">The preview lines.</param>
        /// <param name="width">The width.</param>
        /// <returns>
        /// A thumbnail for the text.
        /// </returns>
        private Bitmap CreateThumbnailForText(IEnumerable<string> previewLines, uint width)
        {
            //  Tamanho do Bitmap
            var thumbnailSize = new Size((int)width, (int)width);

            //  Cria o bitmap.
            var bitmap = new Bitmap(thumbnailSize.Width, thumbnailSize.Height, PixelFormat.Format32bppArgb);

            //  Cria um objeto graphics para manipular o bitmap
            using (var graphics = Graphics.FromImage(bitmap))
            {
                //  Habilita o antialiasing
                graphics.TextRenderingHint = TextRenderingHint.AntiAlias;

                // Desenha o fundo do thumbnail
                // Repare que aqui a imagem do fundo do thumbnail está armazenada em um arquivo de recursos
                graphics.DrawImage(Properties.Resources.Page, 0, 0, thumbnailSize.Width, thumbnailSize.Height);

                //  Create offsets for the text.
                var xOffset = width * 0.2f;
                var yOffset = width * 0.3f;
                var yLimit = width - yOffset;

                graphics.Clip = new Region(new RectangleF(xOffset, yOffset, thumbnailSize.Width - (xOffset * 2), thumbnailSize.Height - width * .1f));

                //  Renderiza cada linha do texto
                foreach (var line in previewLines)
                {
                    graphics.DrawString(line, lazyThumbnailFont.Value, lazyThumbnailTextBrush.Value, xOffset, yOffset);
                    yOffset += 14f;
                    if (yOffset + 14f > yLimit)
                        break;
                }
            }

            //  Retorna o bitmap
            return bitmap;
        }

        /// <summary>
        /// The lazy thumbnail font.
        /// </summary>
        private readonly Lazy<Font> lazyThumbnailFont;

        /// <summary>
        /// The lazy thumbnail text brush.
        /// </summary>
        private readonly Lazy<Brush> lazyThumbnailTextBrush;
    }
}

As you can read in the comment above, it is necessary to load the thumbnail background image into a resource file, and use it in the marked line.

Once this is done, it is necessary to give a "Strong Name" to your project. - In Solution explorer, right click on the project and click properties - Click on the Assintauras (Signing) tab - Check Sign Assembly(Sign the Assembly) - In the dropdown select new. - A day box will be opened. - Enter a name for your Assembly. - Uncheck the password option and click OK.

Once done, just compile your code and test.

To test your Shel extension, use Server Manager, which comes with sharpshell tools. You can also download the program from the sharpshell repository:

https://github.com/dwmkerr/sharpshell

Any questions just ask.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.