Archive for 2011年9月

水滴が付いたガラス越しに景色を見るWPF

2011年9月26日

水滴が付いたガラス越しに景色を見た写真がきれいだったので、WPFで作ってみた。

20070812 026

オリジナルの画像。

作り方

  • 背景

BlurEffect Radius=”15″ ぐらいでぼかす。

  • 水滴の作り方:

Ellipse に同じ画像を貼り付けて、180°回転させて、DropShadowEffectをつける。Ellipse は少し縦長にしてあげる。あとは、水滴をランダムに配置してあげる。水滴は重ならないので、重ならないように配置する。

image

意外とそれっぽく見える。とりあえず、実験用コードをメモっておく。重なり判定はしていません。

using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Media.Effects;

        BitmapImage bi = new BitmapImage(new Uri(“pack://siteoforigin:,,,/20070812 026.jpg”));

        private void Doit()
        {
            for(int i = 0; i < 100; i++)
                CreateRaindrop();
        }

        private void CreateRaindrop()
        {
            Ellipse raindrop = new Ellipse();
            var effect = new DropShadowEffect();
            effect.Direction = 120;
            effect.Opacity = 0.5;
            raindrop.Effect = effect;
            raindrop.Width = 35;
            raindrop.Height = 40;
            raindrop.RenderTransform = GetTransform(GetRnd(0.5));
            raindrop.Fill = new ImageBrush(bi);
            raindrop.Margin = new Thickness(GetRnd(1200) – 650, GetRnd(800) – 400, 0, 0);

            this.MainGrid.Children.Add(raindrop);
        }

        static Random rnd = new Random();
 
        static double GetRnd(double range)
        {
            return (rnd.NextDouble() * range);
        }
       
        private TransformGroup GetTransform(double size)
        {
            var tg = new TransformGroup();
            var st = new ScaleTransform(size, size);
            var rot = new RotateTransform(180);

            tg.Children.Add(st);
            tg.Children.Add(rot);
 
            return tg;
        }
    }
}

広告

Webページを巡回して、処理する

2011年9月23日

会社の文書管理サーバーの中にあるWebページを巡回して処理しないといけないことがあって、でも全社サーバーなのでAPIに触れないので、Webページを読み込んでHTMLを処理しないといけないということがたまにあって、何度か泣きながら同じようなコードを書いているので、スケルトンだけメモっておく。

参照に Microsoft.mshtmlを追加。

<Window x:Class=”Web.MainWindow”
        xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
        xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
        Title=”MainWindow” Height=”344″ Width=”432″>
    <Grid>
        <WebBrowser Margin=”0,44,0,0″ Name=”webBrowser1″  VerticalAlignment=”Stretch” HorizontalAlignment=”Stretch”  LoadCompleted=”webBrowser1_LoadCompleted” />
        <Button Content=”Button” Height=”23″ HorizontalAlignment=”Left” Margin=”24,15,0,0″ Name=”button1″ VerticalAlignment=”Top” Width=”75″ Click=”button1_Click” />
    </Grid>
</Window>

using System;
using System.Windows;
using System.Windows.Navigation;
using System.Collections;

namespace Web
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            DoScan();
        }

        string[] url = {
                           “http://www.yahoo.co.jp”,
                           “http://uchukamen.com”,
                           “http://www.google.co.jp”
                       };

        IEnumerator en = null;

        private void DoScan()
        {
            this.button1.IsEnabled = false;
            en = url.GetEnumerator();
            GoToNextWebPage();
        }

        private void GoToNextWebPage()
        {
            if (en.MoveNext())
                this.webBrowser1.Source = new Uri((string)en.Current);
            else
                this.button1.IsEnabled = true;
        }

        private void webBrowser1_LoadCompleted(object sender, NavigationEventArgs e)
        {
            DoParse();
            GoToNextWebPage();
        }

        private void DoParse()
        {
            string text = ((mshtml.HTMLDocument)this.webBrowser1.Document).documentElement.innerHTML;
            string innterText = ((mshtml.HTMLDocument)this.webBrowser1.Document).documentElement.innerText;
        }

    }
}

Angel Beats! PV6 タイトルをExpression Blend で作ってみた

2011年9月18日

AB PV6 タイトルをExpression Blend で作ってみた

Expression Blendで、30分ぐらいあれば、ノーコーティングで作れます。

もともとのデザインがあって、その通りWPFで作るのは簡単だけど、ゼロからデザインするのは、本当にデザインセンスが問われますね。

<Window
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
x:Class=”WpfApplication6.MainWindow”
x:Name=”Window”
Title=”MainWindow”
Width=”640″ Height=”480″>
<Window.Resources>
<Storyboard x:Key=”OnLoaded1″>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=”(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)” Storyboard.TargetName=”image”>
<EasingDoubleKeyFrame KeyTime=”0″ Value=”227″/>
<EasingDoubleKeyFrame KeyTime=”0:0:0.5″ Value=”5.667″/>
<EasingDoubleKeyFrame KeyTime=”0:0:2″ Value=”5.667″/>
<EasingDoubleKeyFrame KeyTime=”0:0:3″ Value=”5.667″/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=”(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)” Storyboard.TargetName=”image”>
<EasingDoubleKeyFrame KeyTime=”0″ Value=”26″/>
<EasingDoubleKeyFrame KeyTime=”0:0:0.5″ Value=”5.667″/>
<EasingDoubleKeyFrame KeyTime=”0:0:2″ Value=”5.667″/>
<EasingDoubleKeyFrame KeyTime=”0:0:3″ Value=”5.667″/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=”(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)” Storyboard.TargetName=”viewbox”>
<EasingDoubleKeyFrame KeyTime=”0″ Value=”0″/>
<EasingDoubleKeyFrame KeyTime=”0:0:3″ Value=”20″/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=”(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)” Storyboard.TargetName=”viewbox”>
<EasingDoubleKeyFrame KeyTime=”0″ Value=”0″/>
<EasingDoubleKeyFrame KeyTime=”0:0:3″ Value=”20″/>
</DoubleAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty=”(TextElement.Foreground).(SolidColorBrush.Color)” Storyboard.TargetName=”textBlock”>
<EasingColorKeyFrame KeyTime=”0″ Value=”#0087CEFA”/>
<EasingColorKeyFrame KeyTime=”0:0:1″ Value=”LightSkyBlue”/>
<EasingColorKeyFrame KeyTime=”0:0:2″ Value=”LightSkyBlue”/>
<EasingColorKeyFrame KeyTime=”0:0:3″ Value=”#0087CEFA”/>
</ColorAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=”(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)” Storyboard.TargetName=”textBlock”>
<EasingDoubleKeyFrame KeyTime=”0″ Value=”10″/>
<EasingDoubleKeyFrame KeyTime=”0:0:0.5″ Value=”1″/>
<EasingDoubleKeyFrame KeyTime=”0:0:2″ Value=”1″/>
<EasingDoubleKeyFrame KeyTime=”0:0:3″ Value=”1″/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=”(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)” Storyboard.TargetName=”textBlock”>
<EasingDoubleKeyFrame KeyTime=”0″ Value=”10″/>
<EasingDoubleKeyFrame KeyTime=”0:0:0.5″ Value=”1″/>
<EasingDoubleKeyFrame KeyTime=”0:0:2″ Value=”1″/>
<EasingDoubleKeyFrame KeyTime=”0:0:3″ Value=”1″/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=”(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)” Storyboard.TargetName=”textBlock”>
<EasingDoubleKeyFrame KeyTime=”0″ Value=”3″/>
<EasingDoubleKeyFrame KeyTime=”0:0:1″ Value=”0″/>
<EasingDoubleKeyFrame KeyTime=”0:0:2″ Value=”0″/>
<EasingDoubleKeyFrame KeyTime=”0:0:3″ Value=”0″/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=”(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)” Storyboard.TargetName=”textBlock”>
<EasingDoubleKeyFrame KeyTime=”0″ Value=”1″/>
<EasingDoubleKeyFrame KeyTime=”0:0:1″ Value=”0″/>
<EasingDoubleKeyFrame KeyTime=”0:0:2″ Value=”0″/>
<EasingDoubleKeyFrame KeyTime=”0:0:3″ Value=”0″/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=”(UIElement.Opacity)” Storyboard.TargetName=”image”>
<EasingDoubleKeyFrame KeyTime=”0″ Value=”1″/>
<EasingDoubleKeyFrame KeyTime=”0:0:1″ Value=”1″/>
<EasingDoubleKeyFrame KeyTime=”0:0:2″ Value=”1″/>
<EasingDoubleKeyFrame KeyTime=”0:0:3″ Value=”0″/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent=”UIElement.MouseLeftButtonDown”>
<BeginStoryboard x:Name=”OnLoaded1_BeginStoryboard” Storyboard=”{StaticResource OnLoaded1}”/>
</EventTrigger>
<EventTrigger RoutedEvent=”FrameworkElement.Loaded”>
<BeginStoryboard Storyboard=”{StaticResource OnLoaded1}”/>
</EventTrigger>
</Window.Triggers>

<Grid x:Name=”LayoutRoot”>
<Image x:Name=”image” Margin=”0,95,-82,-22″ Source=”CS001.jpg” Stretch=”Fill” RenderTransformOrigin=”0.5,0.5″ HorizontalAlignment=”Right” Width=”290″>
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Image.RenderTransform>
</Image>
<Viewbox x:Name=”viewbox” Margin=”215,166,268,158″ RenderTransformOrigin=”0.5,0.5″>
<Viewbox.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Viewbox.RenderTransform>
<Viewbox.Effect>
<BlurEffect/>
</Viewbox.Effect>
<Ellipse Fill=”#00F4F4F5″ Height=”100″ Stroke=”LightSkyBlue” Width=”100″/>
</Viewbox>
<TextBlock x:Name=”textBlock” Margin=”161,199,161,160″ TextWrapping=”Wrap” FontFamily=”AR DESTINE” FontSize=”21.333″ Foreground=”LightSkyBlue” TextAlignment=”Center” RenderTransformOrigin=”0.5,0.5″>
<TextBlock.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</TextBlock.RenderTransform><Run Language=”ja-jp” Text=”Chief Architect”/><LineBreak/><Run FontSize=”53.333″ Language=”ja-jp” Text=”Uchukamen”/></TextBlock>
</Grid>
</Window>

Sony X-アプリの広告を消す方法

2011年9月17日

iPod から、Sony Walkman A シリーズに乗り換えて、音質はとても気に入っているのだけれども、iTunes に相当する X-アプリがあまりにもひどいので・・・

ひどい点

  • 曲の転送が遅い。
  • UIが遅い。
  • ハングする。ひょっとして、反応が遅すぎるのかもしれない。
  • 音楽取り込み時、起動時、ビデオ再生時など負荷がかかるときに再生がブツブツ途切れる。i7 なのに!
  • 広告がうっとうしい。再生にも影響がある。
  • プレイリストの編集がわかりにくい。

ということで、最後の広告だけでも消そうと思って調べていたら、次の記事が載っていました。

http://blog.livedoor.jp/zirco400/archives/3026025.html

そこで、早速試そうと思ったら、レジストリーのキーがない・・・

ということで、Windows 7 64bit の場合は、次の場所の Promotion を_Promotion などの別の名前に書き換えればOKでした。

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Sony Corporation\SonicStage V\Promotion

プレーヤーの音質はさすがソニーなので、ぜひとも操作性改善に頑張って欲しい。

Expression Blend で画像からパスを作成する方法

2011年9月11日

Expression Blend で画像からパスを作成する方法

 

たまちゃんからのコメントにあるように、塗りつぶし色を少し透明にアルファ値をセットしておくと、透明な状態でデザインできます。設定方法は次の図を見てください。

image

たまちゃん、ありがと~。

Craving Explorer で高音質でダウンロードする方法

2011年9月11日

Youtube, ニコニコ動画から画像や音楽などをダウンロードするのに、Craving ソフトを使用しているが、時々必要になる情報をメモ。

Craving Explorer のダウンロード

http://www.crav-ing.com/

標準だと、MP3の場合 128kBPSだが、このビットレートを上げる方法。

Windows 7の場合。

C:\Program Files (x86)\CravingExplorer\template より、convert.xml を

c:\Users\[ユーザー名]\AppData\Roaming\CravingExplorer\setting にコピーする。

convert.xml の次の場所を変更する。

MP3 320kBPS でダウンロードする場合、-ab 320k と書き換える。

次の例は、MP3 320k というメニューを追加する。

-<Item> <DisplayName>MP3 320k</DisplayName> <Accelerator>M</Accelerator> <ActionName>mp3</ActionName> <CommandLine>-acodec libmp3lame -ac 2 -ar 44100 -ab 320k</CommandLine> <FileExtension>mp3</FileExtension> <BeforeAction/> <AfterAction/> </Item>

それから、Walkman Aシリーズの xアプリが、古いMP4が再生できず、H.264フォーマットで読み込む必要がある。そのための convert.xml  設定方法。

<Device>に次のエントリーを追加

<Item>
    <DisplayName>WALKMAN Aシリーズ</DisplayName>
    <Accelerator>WA</Accelerator>
    <DeviceName>walkmana</DeviceName>
</Item>

<Movie>に次のエントリーを追加

<!– WALKMAN-A –>
<Item>
    <DisplayName>MP4(WALKMAN A 360×270)</DisplayName>
    <Accelerator>M</Accelerator>
    <ActionName>mp4-psp</ActionName>
    <DeviceName>walkmana</DeviceName>
    <CommandLine>-f psp -vcodec libx264 -coder 1 -bufsize 128 -g 250 -s 360×270 -b 1200k -r 30000/1001 -acodec libfaac -ar 44100 -ab 256k</CommandLine>
    <FileExtension>mp4</FileExtension>
    <BeforeAction></BeforeAction>
    <AfterAction></AfterAction>
</Item>

<Item>
    <DisplayName>MP4 ワイド(WALKMAN A 480×270)</DisplayName>
    <Accelerator>W</Accelerator>
    <ActionName>mp4-psp-wide</ActionName>
    <DeviceName>walkmana</DeviceName>
    <CommandLine>-f psp -vcodec libx264 -coder 1 -bufsize 128 -g 250 -s 480×270 -b 1200k -r 30000/1001 -acodec libfaac -ar 44100 -ab 256k</CommandLine>
    <FileExtension>mp4</FileExtension>
    <BeforeAction></BeforeAction>
    <AfterAction></AfterAction>
</Item>

640×480, 720×480 は出力できない模様。

それから、MP3 320k, MP3 256k, MP3 192k の設定は次の通り。

<Item>
    <DisplayName>MP3 320k</DisplayName>
    <Accelerator>M</Accelerator>
    <ActionName>mp3-320k</ActionName>
    <CommandLine>-acodec libmp3lame -ac 2 -ar 44100 -ab 320k</CommandLine>
    <FileExtension>mp3</FileExtension>
    <BeforeAction></BeforeAction>
    <AfterAction></AfterAction>
</Item>

<Item>
    <DisplayName>MP3 256k</DisplayName>
    <Accelerator>M</Accelerator>
    <ActionName>mp3-256k</ActionName>
    <CommandLine>-acodec libmp3lame -ac 2 -ar 44100 -ab 256k</CommandLine>
    <FileExtension>mp3</FileExtension>
    <BeforeAction></BeforeAction>
    <AfterAction></AfterAction>
</Item>

<Item>
    <DisplayName>MP3 192k</DisplayName>
    <Accelerator>M</Accelerator>
    <ActionName>mp-192k</ActionName>
    <CommandLine>-acodec libmp3lame -ac 2 -ar 44100 -ab 192k</CommandLine>
    <FileExtension>mp3</FileExtension>
    <BeforeAction></BeforeAction>
    <AfterAction></AfterAction>
</Item>

System.Windows.Media.Colors 色見本

2011年9月5日

探してしまったので、メモ。

http://msdn.microsoft.com/ja-jp/library/system.windows.media.colors(VS.80).aspx

Predefined colors

原色大辞典

http://www.colordic.org/

WPF であの花を降らせてみた

2011年9月4日

WPF で雪を降らせていたら、あの花を降らせてみてと言われたので、降らせてみた。

あの花 by WPF

 

ついでに、FlowerFactory をMomijiFactory に書き換えて、もみじにしてみた。

もみじ by WPF

 

メインXAML

<Window x:Class=”WpfAnohana.MainWindow”
        Background=”LightGray”
        xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
        xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
        Title=”MainWindow” Height=”480″ Width=”640″ Loaded=”Window_Loaded”>
    <Grid x:Name=”grid”>
        <Grid.Effect>
            <BlurEffect Radius=”5″></BlurEffect>
        </Grid.Effect>
    </Grid>
</Window>

メイン.cs

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace WpfAnohana
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            CreateFlowers();
        //    CreateMomiji();
        }

        // トランジション用(未実装)
        Queue<Viewbox> vb = new Queue<Viewbox>(2020);  

        private void CreateFlowers()
        {
            // Small Size, Fast
            CreateFlowers(0.05, 0.1, 1000, 5);
            // Medium Size
            CreateFlowers(0.1, 0.3, 1000, 10);
            // Large Size
            CreateFlowers(0.3, 1.0, 10, 10);
        }

        private void CreateMomiji()
        {
            // Small Size, Fast
            CreateMomiji(0.05, 0.1, 1000, 5);
            // Medium Size
            CreateMomiji(0.1, 0.3, 1000, 10);
            // Large Size
            CreateMomiji(0.3, 1.0, 20, 10);
        }

        private void CreateFlowers(double minSize, double maxSize, int count, int duration)
        {
            var flowerFactory = new FlowerFactory();
            for (int i = 0; i < count; i++)
            {
                var flower = (Flower)flowerFactory.Create(minSize + GetRnd(maxSize-minSize), duration);
                vb.Enqueue(flower);
                this.grid.Children.Add(flower);
                flower.BeginAnimation();
            }
        }

        private void CreateMomiji(double minSize, double maxSize, int count, int duration)
        {
            var momijiFactory = new MomijiFactory();
            for (int i = 0; i < count; i++)
            {
                var momiji = (Momiji)momijiFactory.Create(minSize + GetRnd(maxSize – minSize), duration);
                vb.Enqueue(momiji);
                this.grid.Children.Add(momiji);
                momiji.BeginAnimation();
            }
        }

        static Random rnd = new Random();

        static double GetRnd(double range)
        {
            return (rnd.NextDouble() * range);
        }
    }
}

ShapeFactory.cs

using System;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace WpfAnohana
{
    /// <summary>
    /// ———————————————————————–
    /// Factory パターン
    /// ———————————————————————–
    /// </summary>
    abstract public class ShapeFactory
    {
        abstract public Viewbox Create(double size, int duration);
    }

    /// <summary>
    /// ———————————————————————–
    /// </summary>
    public class AnimatedViewbox : Viewbox
    {
        protected DoubleAnimationUsingKeyFrames daukfRot = null;
        protected DoubleAnimationUsingKeyFrames daukfX = null;
        protected DoubleAnimationUsingKeyFrames daukfY = null;

        public RotateTransform RotTrans { get; set; }
        public TranslateTransform TransX { get; set; }
        public TranslateTransform TransY { get; set; }

        public static DoubleAnimationUsingKeyFrames DoubleAnimation(TimeSpan beginTime, TimeSpan duration, int from, int to)
        {
            var daukfRot = new DoubleAnimationUsingKeyFrames();

            var ldkfR1 = new LinearDoubleKeyFrame
            {
                KeyTime = KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0)),
                Value = from
            };

            var ldkfR2 = new LinearDoubleKeyFrame
            {
                KeyTime = KeyTime.FromTimeSpan(duration),
                Value = to
            };

            daukfRot.KeyFrames.Add(ldkfR1);
            daukfRot.KeyFrames.Add(ldkfR2);
            daukfRot.BeginTime = beginTime;
            daukfRot.Duration = duration;
            daukfRot.RepeatBehavior = RepeatBehavior.Forever;

            return daukfRot;
        }

        public void BeginAnimation()
        {
            TransX.BeginAnimation(TranslateTransform.XProperty, daukfX);
            TransY.BeginAnimation(TranslateTransform.YProperty, daukfY);
            RotTrans.BeginAnimation(RotateTransform.AngleProperty, daukfRot);
        }

        static Random rnd = new Random();

        static double GetRnd(double range)
        {
            return (rnd.NextDouble() * range);
        }
    }
}

FlowerFactory.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace WpfAnohana
{
    /// <summary>
    /// ———————————————————————–
    /// </summary>
    public class FlowerFactory : ShapeFactory
    {
        public override Viewbox Create(double size, int duration)
        {
            var flower = new Flower(size, duration);
            return flower;
        }
    }

    /// <summary>
    /// ———————————————————————–
    /// </summary>
    public class Flower : AnimatedViewbox
    {
        public Flower(double size, int duration)
        {
            Reverse = true;
            RenderTransform = GetTransform(size);
            HorizontalAlignment = HorizontalAlignment.Left;
            VerticalAlignment = VerticalAlignment.Top;
            RenderTransformOrigin = new Point(0.5, 0.5);
            Width = 100;
            Height = 100;
            Child = CreateFlowerPath(FlowerColor.GetNext());

            CreateAnimation(duration);
        }

        public bool Reverse { get; set; }

        private void CreateAnimation(int duration)
        {
            var begin0 = new TimeSpan(0, 0, 0);
            var duration10 = new TimeSpan(0, 0, duration);
            var beginTimeRnd = new TimeSpan(0, 0, 0, 0, (int)GetRnd(duration * 1000));

            int fromY = Reverse ? 600 : -50;
            int toY = Reverse ? -50: 600;

            daukfRot = DoubleAnimation(begin0, duration10, 0, 360 * 2);
            daukfX = DoubleAnimation(beginTimeRnd, duration10, 0, (int)GetRnd(200) – 100);
            daukfY = DoubleAnimation(beginTimeRnd, duration10, fromY, toY);
        }

        private TransformGroup GetTransform(double size)
        {
            var tg = new TransformGroup();
            var st = new ScaleTransform(size, size);
            var skewt = new SkewTransform();
            var tt = new TranslateTransform(GetRnd(640+200) – 100, -150);
            TransX = new TranslateTransform(0, 0);
            TransY = new TranslateTransform(0, 0);
            RotTrans = new RotateTransform();

            tg.Children.Add(st);
            tg.Children.Add(skewt);
            tg.Children.Add(RotTrans);
            tg.Children.Add(TransY);
            tg.Children.Add(TransX);
            tg.Children.Add(tt);

            return tg;
        }

        private static Shape CreateFlowerPath(Color col)
        {
            const string PathData = “M248,64 C236.5247,64.625058 225.71435,67.192184 215.5,71.5 L207.5,95.5 191.5,79.5 C179.10929,77.102304 168.53048,80.027027 159.5,87.5 159.50162,99.540561 161.46431,108.60788 167.5,111.5 L183.5,119.5 159.5,135.5 C160.12292,156.23214 162.17492,169.92602 167.5,167.5 172.91066,172.67869 180.71148,173.07705 191.5,167.5 L207.5,151.5 C203.2411,162.05534 202.55968,170.46419 207.5,175.5 219.38597,184.51719 230.14356,187.65745 239.5,183.5 L255.5,167.5 C252.80927,155.47101 245.02601,144.74873 231.5,135.5 L263.5,143.5 C272.5318,139.39663 278.23003,131.78108 279.5,119.5 276.83333,114.16667 274.16667,108.83333 271.5,103.5 262.70483,100.69259 251.88845,100.91719 239.5,103.5 248.65115,105.75263 260.3255,80.446287 248,64 z”;
           
            var g = PathGeometry.Parse(PathData);
            var br = new SolidColorBrush(col);
            var p = new Path();
            p.Width = 50;
            p.Height = 50;
            p.RenderTransformOrigin = new Point(0.5, 0.5);
            p.Stretch = Stretch.Fill;
            p.Data = g;
            p.Fill = br;

            return p;
        }

        static Random rnd = new Random();

        static double GetRnd(double range)
        {
            return (rnd.NextDouble() * range);
        }

        class FlowerColor
        {
            static Color[] col = {
                          Color.FromRgb(222,89,182),
                              Color.FromRgb(247,203,224),
                              Color.FromRgb(239,78,100),
                              Color.FromRgb(243,141,147),
                              Color.FromRgb(240,154,232),
                              Color.FromRgb(244,228,188),
                              Color.FromRgb(246,187,167)
                      };

            static int i = -1;
            public static Color GetNext()
            {
                if (++i >= col.Length)
                    i = 0;
                return col[i];
            }
        }
    }
}

MomijiFactory.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace WpfAnohana
{

    /// <summary>
    /// ———————————————————————–
    /// </summary>
    public class MomijiFactory : ShapeFactory
    {
        public override Viewbox Create(double size, int duration)
        {
            var momiji = new Momiji(size, duration);
            return momiji;
        }
    }

    /// <summary>
    /// ———————————————————————–
    /// </summary>
    public class Momiji : AnimatedViewbox
    {
        public Momiji(double size, int duration)
        {
            RenderTransform = GetTransform(size);
            HorizontalAlignment = HorizontalAlignment.Left;
            VerticalAlignment = VerticalAlignment.Top;
            RenderTransformOrigin = new Point(0.5, 0.5);
            Width = 100;
            Height = 100;
            Child = CreateMomijiPath(MomijiColor.GetNext());

            CreateAnimation(duration);
        }

        private void CreateAnimation(int duration)
        {
            var begin0 = new TimeSpan(0, 0, 0);
            var duration10 = new TimeSpan(0, 0, duration);
            var beginTimeRnd = new TimeSpan(0, 0, 0, 0, (int)GetRnd(duration * 1000));

            daukfRot = DoubleAnimation(begin0, duration10, 0, 360 * 2);
            daukfX = DoubleAnimation(beginTimeRnd, duration10, 0, (int)GetRnd(200) – 100);
            daukfY = DoubleAnimation(beginTimeRnd, duration10, -50, 600);
        }

        private TransformGroup GetTransform(double size)
        {
            var tg = new TransformGroup();
            var st = new ScaleTransform(size, size);
            var skewt = new SkewTransform();
            var tt = new TranslateTransform(GetRnd(640) – 100, -150);
            TransX = new TranslateTransform(0, 0);
            TransY = new TranslateTransform(0, 0);
            RotTrans = new RotateTransform();

            tg.Children.Add(st);
            tg.Children.Add(skewt);
            tg.Children.Add(RotTrans);
            tg.Children.Add(TransY);
            tg.Children.Add(TransX);
            tg.Children.Add(tt);

            return tg;
        }

        private static Shape CreateMomijiPath(Color col)
        {
            const string PathData = “M183.66667,86.666667 C189.39235,102.51222 195.97031,115.69911 204.00303,124.34783 189.46184,124.37625 176.55191,127.63058 166.26051,130.07866 177.67961,136.62725 192.00787,141.50314 209.25719,141.39676 203.19164,149.57713 198.0335,156.49435 192.99912,166.33255 202.42621,162.74626 210.94614,156.64738 218.66605,148.33266 L222.66553,167.66588 C225.54016,165.52929 227.12504,154.35884 228.999,141.99936 234.06358,144.63928 238.15358,153.77991 241.33226,168.99921 L243.66592,167.99921 C241.1493,155.99855 236.78856,146.70538 230.66566,139.99937 241.69194,144.10578 251.73257,143.90948 260.99883,140.3327 255.36431,137.34626 248.38965,134.93892 240.33229,132.99941 250.52631,127.61701 259.03319,119.28195 265.66548,107.66621 L234.3321,118.99948 C236.99567,104.86417 236.63427,91.185053 232.99878,77.999712 226.74482,85.30016 221.8588,98.979918 218.33224,118.99948 209.59223,103.54312 197.83014,93.109381 183.66667,86.666667 z”;

            var g = PathGeometry.Parse(PathData);
            var br = new SolidColorBrush(col);
            var p = new Path();
            p.RenderTransformOrigin = new Point(0.5, 0.5);
            p.Stretch = Stretch.Fill;
            p.Data = g;
            p.Fill = br;

            return p;
        }

        static Random rnd = new Random();

        static double GetRnd(double range)
        {
            return (rnd.NextDouble() * range);
        }

        class MomijiColor
        {
            static Color[] col = {
                          Color.FromRgb((byte)0xdc,(byte)0x14,(byte)0x3c),
                          Color.FromRgb(239, 119,33),
                          Color.FromRgb(255, 51,45),
                          Color.FromRgb(239, 119,33),
                          Color.FromRgb(255, 51,45),
                          Colors.Gold,
                          Color.FromRgb(34,136,34)
                      };

            static int i = -1;
            public static Color GetNext()
            {
                if (++i >= col.Length)
                    i = 0;
                return col[i];
            }
        }
    }
}

yield return では Reset() できない

2011年9月3日

yield return で、Reset() しようとしたら、例外が発生したので、メモ。

yield return を使って、1つづつ値を処理しようと思ったのですが、一般には次のような foreach, IEnumerator を使って、列挙することができます。

using System;
using System.Collections.Generic;
using System.Collections;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClass mc = new MyClass();

            foreach (string s in mc)
                Console.WriteLine(s);

            IEnumerator<string> e = mc.GetEnumerator();
            while (e.MoveNext())
            {
                Console.WriteLine(e.Current);
            }            Console.ReadLine();
        }

        public class MyClass
        {
            public IEnumerator<string> GetEnumerator()
            {
                yield return “Hello1”;
                yield return “Hello2”;
                yield return “Hello3”;
                yield return “Hello4”;
            }
        }
    }
}

ある限られた要素を、無限に Enumerate できるようにしようと思って、yield return で与えられた Enumerable を Enumerate して、MoveNext()できなかったら、最初にReset()したが、Reset()のところで、NotSupportedException 例外となりました。

IEnumerator<string> col = mc.GetEnumerator();

for (int i = 0; i < 50; i++)
{
    if (col.MoveNext() == false)
    {
        col.Reset();   // <<<<<<<<<<<<<< ここで NotSupportedException 例外
        col.MoveNext();
    }
    Console.WriteLine(col.Current);
}

aetos さんのところに詳細に解説が載ってました。http://blogs.wankuma.com/shannon/archive/2007/07/10/84596.aspx

yield は Reset() のところまで実装していないので、当然リセットできないということですね。なお、これを回避するには、Reset()ではなく、Enumerator を取り直せば、繰り返しできる。

ある限られた要素を、無限に列挙するのは、あえてやるとすると、こんな感じ?

MyClass2 mc2 = new MyClass2();

for (int i = 0; i < 50; i++)
{
    Console.WriteLine(mc2.GetNext());
}

public class MyClass2
{
    string[] test = { “Hello1”, “Hello2”, “Hello3”, “Hello4”, “Hello5” };
    static int i = -1;
    public string GetNext()
    {
        if (++i >= test.Length)
            i = 0;
        return test[i];
    }
}

neueccさんからの linq のコードを教えてもらった。なるほど~。有限回の繰り返しなら、シンプルでいいねー。

http://gyazo.com/6c17ca767c84e4f695a3f4420a66dba2

var array = new[] { “Hello1”, “Hello2” };
var query = Enumerable.Repeat(array, 2).SelectMany(xs=>xs);

foreach(var item in query)
    Console.WriteLine(item);