LoginSignup
1
1

More than 3 years have passed since last update.

C# - Windows10のログイン画面の壁紙をサムネイル表示してドラッグ&ドロップでエクスプローラにコピーするツール作ってみた

Last updated at Posted at 2019-11-30

ロック画面の画像(参考サイト#1を参照ください)をサムネイル表示して、欲しい画像だけ簡単にコピーできるようにしたいと思ったのでC#で作ってみた。

画面キャプチャ

image.png

使い方

画像を選んでデスクトップ(他のフォルダでも可)にドラッグ&ドロップすると、ファイルがコピーされます。
コピー後の拡張子の変更(.jpgにしてください)は手動でお願いします。(一時ファイルを作るのが面倒なため) 使ってて不便すぎたので拡張子を付加するようにした(テンポラリフォルダ使用します)。

ソースコード


using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;


class WinWallpaperPreview : Form
{
    class ImageItemInfo
    {
        public string FullPath{get; private set;}
        public System.Drawing.Size Size{get; private set;}
        public int Width {get{return Size.Width;}}
        public int Height {get{return Size.Height;}}

        public ImageItemInfo(string fullPath, Size size) {
            FullPath = fullPath;
            Size = size;
        }
    }

    class MyListViewItemComparer : IComparer
    {
        public int Compare(object item1, object item2)
        {
            var itemInfo1 = (ImageItemInfo)((ListViewItem)item1).Tag;
            var itemInfo2 = (ImageItemInfo)((ListViewItem)item2).Tag;

            int tmp = itemInfo1.Width.CompareTo(itemInfo2.Width);
            if ( tmp == 0 ) { tmp = itemInfo1.Height.CompareTo(itemInfo2.Height); }
            return tmp;
        }
    }

    // ------------------------------------------------------------

    static readonly string imageDir = GetDefaultWallpaperPath();

    ListView lsv;
    ImageList imgList;
    //StatusStrip sts;

    // ------------------------------------------------------------

    static string GetDefaultWallpaperPath()
    {
        return Path.Combine(Environment.GetEnvironmentVariable("LOCALAPPDATA"),
                             @"Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\Assets");
    }

    // 幅w、高さhのImageオブジェクトを作成
    Image CreateSmallImage(Image image, Size size)
    {
        int w = size.Width;
        int h = size.Height;
        Bitmap canvas = new Bitmap(w, h);

        Graphics g = Graphics.FromImage(canvas);
        g.FillRectangle(Brushes.LightGray, 0, 0, w, h);

        float fw = (float)w / (float)image.Width;
        float fh = (float)h / (float)image.Height;

        float scale = Math.Min(fw, fh);
        fw = image.Width * scale;
        fh = image.Height * scale;

        g.DrawImage(image, (w - fw) / 2, (h - fh) / 2, fw, fh);
        g.Dispose();

        return canvas;
    }

    void LoadImages()
    {
        string[] files = Directory.GetFiles(imageDir);
        int count = 0;

        foreach (string filePath in files)
        {
            Image original;
            try {
                original = Image.FromFile(filePath); // 拡張子がなくても自動判別してくれる
            }
            catch ( Exception ex ) { // かなり乱暴なのでマネしないように...
                Console.WriteLine(ex);
                Console.WriteLine("Ignored: " + Path.GetFileName(filePath));
                continue;
            }
            if ( original == null ) {
                Console.WriteLine("Ignored: " + Path.GetFileName(filePath));
                continue;
            }

            Image smallImage = CreateSmallImage(original, imgList.ImageSize);
            imgList.Images.Add(smallImage);
            string text = original.Size.Width.ToString() + " x " + original.Size.Height.ToString();
            lsv.Items.Add(text, count);
//            lsv.Items.Add(Path.GetFileName(filePath), count);
            lsv.Items[count].Tag = new ImageItemInfo(filePath, original.Size);
            count++;

            original.Dispose();
            smallImage.Dispose();
        }

        lsv.ListViewItemSorter = new MyListViewItemComparer();
    }

    //void Lsv_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
    //{
    //    Console.WriteLine(e.Action);
    //}

    void Lsv_ItemDrag(Object sender, ItemDragEventArgs e)
    {
        var item = (ListViewItem)(e.Item);
        string orgPath = ((ImageItemInfo)item.Tag).FullPath;

        // テンポラリフォルダに拡張子(.jpg)付きのファイルを作る
        string tempPath = Path.ChangeExtension(Path.Combine(Path.GetTempPath(), Path.GetFileName(orgPath)), ".jpg");
        Console.WriteLine(tempPath);
        if ( !File.Exists(tempPath) ) {
            try {
                File.Copy(orgPath, tempPath);
            }
            catch ( IOException exception ) {
                MessageBox.Show(exception.ToString());
                return;
            }
        }

        //ドラッグ&ドロップ処理を開始する
        IDataObject iData = new DataObject(DataFormats.FileDrop, new string[]{tempPath});
        lsv.DoDragDrop(iData, DragDropEffects.Copy);
    }



    /*
    壁紙変更は下記でやれるらしい
    [DllImport("User32.DLL")]
    public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, string pvParam, uint fWinIni);
    public static uint SPI_SETDESKWALLPAPER = 0x0014;

    String sName = fullPath;
    SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, sName, 0);
    */


    WinWallpaperPreview()
    {
        int width = 100;
        int height = 80;

        imgList = new ImageList();
        imgList.ImageSize = new Size(width, height);

        lsv = new ListView();
        lsv.View = View.Tile;
        lsv.LargeImageList = imgList;
        lsv.Dock = DockStyle.Fill;
        lsv.MultiSelect = false;
        //lsv.SelectedIndexChanged += ;
        lsv.ItemDrag += Lsv_ItemDrag;
        //lsv.QueryContinueDrag += Lsv_QueryContinueDrag;
        Controls.Add(lsv);

        //sts = new StatusStrip();
        //Controls.Add(sts);

        Load += (s,e)=>{LoadImages();};
        FormClosed += (s,e)=>{CleanUpTempDir();};

        Text = "Wallpaper Preview";
        ClientSize = new Size(700,500);
    }

    void CleanUpTempDir()
    {
        string tempDir = Path.GetTempPath(); // 変えるな危険!
        if ( Directory.Exists(tempDir) ) {
            try {
                Console.WriteLine(tempDir);
                //Directory.Delete(tempDir, true); // サブフォルダごと削除
            }
            catch ( IOException exception ) {
                Console.WriteLine(exception);
            }
        }
    }

    [STAThread]
    static void Main(string[] args)
    {
        Application.Run(new WinWallpaperPreview());
    }
}

参考サイト

  1. Windows10のロック画面の画像がキレイだから壁紙のスライドショーにしたいと思った - Qiita
  2. ListViewコントロールでサムネイル画像を一覧表示するには? - @IT
  3. 異種アプリへドラッグアンドドロップする方法 - C# と VB.NET の質問掲示板
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1