画像検索Viewer


WPF + XAMLで画像検索Viewerというのを作った。
googleのimage検索結果を表示してくれる。
検索された画像をクリックすると拡大表示する。


Silverlightに移植しようかと思ったけど、silverlightはhtmlの取得が制限されてた気がするのでやめた。


ちょっと面白いなー と思ったけど、あんまり使い道ないね。
もっと面白い機能ないかな。


以下C#XAMLのソース。

ソースコード:C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net;
using System.Web;
using System.IO;
using System.Text.RegularExpressions;

namespace WpfApplication
{
    /// <summary>
    /// Window1.xaml の相互作用ロジック
    /// </summary>
    public partial class Window1 : Window
    {
        struct ImgPos
        {
            public int x_pos;
            public int y_pos;
        }

        /* Url格納用 */
        string[] arrayPath = new string[256];
        /* Url用カウンタ */
        int urlCount = 0;
        /* 表示用画像カウンタ */
        int imgNum = 0;
        /* Canvas格納用 */
        Canvas[] arrayCanvas = new Canvas[256];
        /* 表示画像確認用 */
        int[] showImgCount = new int[256];
        /* 拡大表示FG */
        bool showFG = false;
        /* 拡大表示保存用 */
        int showImgNum = -1;
        /* 表示位置保存用 */
        ImgPos[] imgPos = new ImgPos[9];

        public Window1()
        {
            InitializeComponent();

            // URL取得
            //this.GetImageUrl();

            // Canvas初期化
            this.CanvasInit();

            // 初期化
            //this.Init();
        }

        /* Canvas初期化 */
        private void CanvasInit()
        {
            arrayCanvas[0] = canvas1;
            arrayCanvas[1] = canvas2;
            arrayCanvas[2] = canvas3;
            arrayCanvas[3] = canvas4;
            arrayCanvas[4] = canvas5;
            arrayCanvas[5] = canvas6;
            arrayCanvas[6] = canvas7;
            arrayCanvas[7] = canvas8;
            arrayCanvas[8] = canvas9;

            int cnt = 0;
            int x = 32;
            int y = 61;

            /* 3×3で配置 */
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    imgPos[cnt] = new ImgPos();
                    imgPos[cnt].x_pos = x;
                    imgPos[cnt].y_pos = y;

                    Canvas.SetLeft(arrayCanvas[cnt], x); Canvas.SetTop(arrayCanvas[cnt], y);


                    x += 180;
                    cnt++;
                }

                x = 32;
                y += 150;
            }
        }

        /* 初期化 */
        private void Init()
        {
            int j = 0;

            for (int i = imgNum; i < imgNum + 9; i++)
            {
                /* 画像読み込み */
                BitmapImage bmp = new BitmapImage();
                bmp.BeginInit();
                bmp.UriSource = new Uri(arrayPath[i], UriKind.Absolute);
                bmp.EndInit();

                /* Imageに設定 */
                Image img = new Image();
                img.Source = bmp;
                img.Width = 160;
                img.Height = 114;

                /* 画像を登録 */
                arrayCanvas[j].Children.Add(img);

                /* 表示画像確認 */
                showImgCount[j] = i;

                j++;
            }
        }

        /* 画像URL取得 */
        private void GetImageUrl(string strURL)
        {
            // HTML取得
            WebClient wc = new WebClient();

            Stream st = wc.OpenRead(strURL);

            Encoding enc = Encoding.GetEncoding("UTF-8");
            StreamReader sr = new StreamReader(st, enc);
            string html = sr.ReadToEnd();
            sr.Close();

            st.Close();

            // 画像パス抽出
            Regex r;
            int count = 0;
            urlCount = 0;
            r = new Regex("http(s?)://[\\w\\.\\-/:&?,=#]+\\.(jpg|jpeg|gif|png|bmp)");

            Match m;
            m = r.Match(html);
            System.IO.StreamWriter sw = new System.IO.StreamWriter("test.txt", false, System.Text.Encoding.GetEncoding(932));


            while (m.Success)
            {
                if (m.Value.Length < 80)
                {
                    // URLのみを抽出
                    //arrayPath[count] = m.Value.Substring(m.Value.IndexOf("\"") + 1, m.Value.LastIndexOf("\"") - m.Value.IndexOf("\"") - 1);
                    arrayPath[count] = m.Value;
                    sw.WriteLine(arrayPath[count]);
                    count++;

                    urlCount++;
                }

                //次に一致する対象を検索
                m = m.NextMatch();
            }

            sw.Flush();
            sw.Close();
        }

        /* 左カーソルクリックイベント */
        private void canvas10_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (imgNum > 0 && showFG == false)
            {
                imgNum -= 9;

                for (int i = 0; i < 9; i++)
                {
                    arrayCanvas[i].Children.Clear();
                }

                /* 初期化 */
                this.Init();
            }
        }

        /* 右カーソルクリックイベント */
        private void canvas11_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (urlCount > (imgNum + 18) && showFG == false)
            {
                imgNum += 9;

                for (int i = 0; i < 9; i++)
                {
                    arrayCanvas[i].Children.Clear();
                }

                /* 初期化 */
                this.Init();
            }
        }

        /* 画像クリックイベント */
        private void canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Canvas canvas = (Canvas)sender;

            /* 拡大表示されていない場合 */
            if (showFG == false)
            {
                for (int i = 0; i < 9; i++)
                {
                    /* クリックされたCanvasの特定 */
                    if (arrayCanvas[i].Equals(canvas))
                    {
                        //arrayCanvas[i].Width = imgSize[showImgCount[i]].x_size;
                        //arrayCanvas[i].Height = imgSize[showImgCount[i]].y_size;
                        
                        // 画像拡大
                        Canvas.SetZIndex(arrayCanvas[i], 9);
                        Image img = (Image)arrayCanvas[i].Children[0];
                        img.Width = 320;
                        img.Height = 240;

                        // 位置の変更
                        Canvas.SetTop(arrayCanvas[i], 150);
                        Canvas.SetLeft(arrayCanvas[i], 140);

                        // 拡大したCanvasの保存
                        showImgNum = i;

                        // 拡大表示中に変更
                        showFG = true;

                        // Maskを適用
                        //this.image3.Visibility = Visibility.Visible;
                        //this.image3.Opacity = 0.4;
                    }
                }
            }
            /* 拡大表示されている場合 */
            else if (showFG == true)
            {
                // 画像を元に戻す
                Canvas.SetZIndex(arrayCanvas[showImgNum], showImgNum);
                Image img = (Image)arrayCanvas[showImgNum].Children[0];
                img.Width = 160;
                img.Height = 114;

                // 位置の変更
                Canvas.SetTop(arrayCanvas[showImgNum], imgPos[showImgNum].y_pos);
                Canvas.SetLeft(arrayCanvas[showImgNum], imgPos[showImgNum].x_pos);

                // 拡大したCanvasの破棄
                showImgNum = -1;

                // 拡大表示なし
                showFG = false;

                // Maskを破棄
                //this.image3.Visibility = Visibility.Hidden;
                //this.image3.Opacity = 0.0;
            }
        }

        /* イメージを検索 */
        private void Search_Click(object sender, RoutedEventArgs e)
        {
            // 検索文字列を取得
            string strSearch = this.SearchText.Text;

            // URLエンコード
            string encodedString = HttpUtility.UrlEncode(strSearch);

            // googleImage用のURL作成
            string strURL;

            strURL = "http://images.google.co.jp/images?hl=ja&q=" + encodedString + "&lr=&um=1&ie=UTF-8&sa=N&tab=wi&start=1";

            if (encodedString.Length > 0)
            {
                // Canvas初期化
                for (int i = 0; i < 9; i++)
                {
                    arrayCanvas[i].Children.Clear();
                }

                // URL取得
                this.GetImageUrl(strURL);

                // 初期化
                this.Init();
            }

        }
    }
}


ソースコード:XAML

<Window x:Class="WpfApplication4.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="画像検索Viewer" Height="616" Width="600">
    <Grid>
        <Canvas Name="RootCanvas" Margin="0,63.346,0,0">
            <Canvas MouseLeftButtonDown="canvas_MouseLeftButtonDown" Canvas.Left="32.867" Canvas.Top="61.447" Height="114.32" Name="canvas1" Width="160.048"></Canvas>
            <Canvas MouseLeftButtonDown="canvas_MouseLeftButtonDown" Canvas.Left="212.921" Canvas.Top="61.447" Height="114.32" Name="canvas2" Width="160.048"></Canvas>
            <Canvas MouseLeftButtonDown="canvas_MouseLeftButtonDown" Canvas.Left="394.404" Canvas.Top="61.447" Height="114.32" Name="canvas3" Width="160.048" />
            <Canvas MouseLeftButtonDown="canvas_MouseLeftButtonDown" Canvas.Left="32.867" Canvas.Top="211.492" Height="114.32" Name="canvas4" Width="160.048" />
            <Canvas MouseLeftButtonDown="canvas_MouseLeftButtonDown" Canvas.Left="212.921" Canvas.Top="211.492" Height="114.32" Name="canvas5" Width="160.048" />
            <Canvas MouseLeftButtonDown="canvas_MouseLeftButtonDown" Canvas.Left="394.404" Canvas.Top="211.492" Height="114.32" Name="canvas6" Width="160.048"></Canvas>
            <Canvas MouseLeftButtonDown="canvas_MouseLeftButtonDown" Canvas.Left="32.867" Canvas.Top="361.537" Height="114.32" Name="canvas7" Width="160.048" />
            <Canvas MouseLeftButtonDown="canvas_MouseLeftButtonDown" Canvas.Left="212.921" Canvas.Top="361.537" Height="114.32" Name="canvas8" Width="160.048" />
            <Canvas MouseLeftButtonDown="canvas_MouseLeftButtonDown" Canvas.Left="394.404" Canvas.Top="361.537" Height="114.32" Name="canvas9" Width="160.048" />
            <Canvas MouseLeftButtonDown="canvas10_MouseLeftButtonDown" Canvas.Left="212.921" Canvas.Top="33.633" Height="19.998" Name="canvas10" Width="20">
                <Image Canvas.Left="0" Canvas.Top="0" Height="19.998" Name="image1" Stretch="Fill" Width="20" Source="/WpfApplication4;component/left.gif" />
            </Canvas>
            <Canvas MouseLeftButtonDown="canvas11_MouseLeftButtonDown" Canvas.Left="352.969" Canvas.Top="33.633" Height="19.998" Name="canvas11" Width="20">
                <Image Canvas.Left="0" Canvas.Top="0" Height="19.998" Name="image2" Stretch="Fill" Width="20" Source="/WpfApplication4;component/right.gif" />
            </Canvas>
            <Image Canvas.Left="0" Canvas.Top="0" Height="512" Name="image3" Stretch="Fill" Width="578" Source="/WpfApplication4;component/mask.bmp" Opacity="0" Visibility="Hidden" />
          
        </Canvas>
        <Canvas Height="63.346" Name="canvas12" VerticalAlignment="Top">
            <TextBox Canvas.Left="32.867" Canvas.Top="38.885" Height="24.442" Name="SearchText" Width="164.891" />
            <Label Canvas.Left="32.867" Canvas.Top="9.999" Height="22.22" Name="label1" Width="160.048">検索文字列</Label>
            <Button Canvas.Left="212.921" Canvas.Top="38.885" Height="23.331" Name="Search" Width="75.548" Click="Search_Click" Background="Pink">イメージ検索</Button>
        </Canvas>
    </Grid>
</Window>