WPF 如何画一颗心

原文: WPF 如何画一颗心

   如何用WPF画一个心。

   MainWindow.xaml

<Window x:Class="Heart.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Heart"
        mc:Ignorable="d"
        Title="MainWindow" Height="600" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="66*"/>
            <RowDefinition Height="74*"/>
            <RowDefinition Height="77*"/>
            <RowDefinition Height="98*"/>
            <RowDefinition Height="69*"/>
            <RowDefinition Height="62*"/>
            <RowDefinition Height="72*"/>
            <RowDefinition Height="52*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="134*"/>
            <ColumnDefinition Width="525*"/>
            <ColumnDefinition Width="134*"/>
        </Grid.ColumnDefinitions>
        <Button Content="画心" Grid.Column="0" Grid.Row="1" Click="ButtonStart_Click" Width="100"></Button>
        <Canvas x:Name="canvas_Shape" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="500" Margin="12,0" Grid.Column="1" Grid.RowSpan="8"/>
    </Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Threading;

namespace Heart
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            imageList = new List<System.Windows.Controls.Image>();
            imageList1 = new List<System.Windows.Controls.Image>();
            CreateHeartLine(true);
            CreateHeartLine(false);

            m_iImageCount = imageList.Count;
        }
        private int maxStep = 50;
        private double radius;
        private double centerPt;
        private Bitmap m_Snow;
        private Bitmap m_Snow1;
        private int m_iImageCount = 0;

        private List<System.Windows.Controls.Image> imageList = null;
        private List<System.Windows.Controls.Image> imageList1 = null;
        [DllImport("gdi32")]
        static extern int DeleteObject(IntPtr o);
        private BitmapSource GetBitmapSource(Bitmap bitmap)
        {
            IntPtr inptr = bitmap.GetHbitmap();
            BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                inptr, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
            DeleteObject(inptr);
            return bitmapSource;
        }

        private void SetImageSoure(System.Windows.Controls.Image img , Bitmap mSnow)
        {
            BitmapSource bitmapSource = GetBitmapSource(mSnow);
            img.Source = bitmapSource;
        }
        private void CreateHeartLine(bool bShow)
        {
            centerPt = canvas_Shape.Width / 2;
            radius = canvas_Shape.Width / 6;
            for (int i = 0; i < maxStep; i++)
            {
                System.Windows.Controls.Image img = new System.Windows.Controls.Image();
                BitmapSource bitmapSource;
                
                if (bShow)
                {
                    bitmapSource  = GetBitmapSource(Snow);
                    img.Source = bitmapSource;
                    img.Visibility = Visibility.Hidden;
                    imageList.Add(img);
                }
                else
                {
                    bitmapSource = GetBitmapSource(Snow1);
                    img.Source = bitmapSource;
                    imageList1.Add(img);
                }
                double angle = 2 * Math.PI / maxStep * i;
                double r = 2 * radius * (1 - Math.Sin(angle));
                //桃形心
                double x = centerPt - 16 * (Math.Sin(angle) * Math.Sin(angle) * Math.Sin(angle)) * 10;//
                double y = centerPt - (13 * Math.Cos(angle) - 5 * Math.Cos(2 * angle) - 2 * Math.Cos(3 * angle) - Math.Cos(4 * angle)) * 10;//
                Canvas.SetLeft(img, x);
                Canvas.SetTop(img, y);
                canvas_Shape.Children.Add(img);
            }
        }

        private Bitmap Snow
        {
            get
            {
                if (m_Snow == null)
                {
                    m_Snow = new Bitmap(32, 32);
                    using (Graphics g = Graphics.FromImage(m_Snow))
                    {
                        g.SmoothingMode = SmoothingMode.AntiAlias;
                        g.Clear(System.Drawing.Color.Transparent);
                        g.TranslateTransform(16, 16, MatrixOrder.Append);
                        System.Drawing.Color black = System.Drawing.Color.FromArgb(255, 255, 255);
                        System.Drawing.Color white = System.Drawing.Color.FromArgb(255, 0, 255);
                        DrawSnow(g, new SolidBrush(black), new System.Drawing.Pen(black, 3f));
                        DrawSnow(g, new SolidBrush(white), new System.Drawing.Pen(white, 2f));
                        g.Save();
                    }
                }
                return m_Snow;
            }
        }
        private Bitmap Snow1
        {
            get
            {
                if (m_Snow1 == null)
                {
                    m_Snow1 = new Bitmap(32, 32);
                    using (Graphics g = Graphics.FromImage(m_Snow1))
                    {
                        g.SmoothingMode = SmoothingMode.AntiAlias;
                        g.Clear(System.Drawing.Color.Transparent);
                        g.TranslateTransform(16, 16, MatrixOrder.Append);
                        System.Drawing.Color black = System.Drawing.Color.FromArgb(255, 255, 255);
                        System.Drawing.Color white = System.Drawing.Color.FromArgb(254, 194, 253);
                        DrawSnow(g, new SolidBrush(black), new System.Drawing.Pen(black, 3f));
                        DrawSnow(g, new SolidBrush(white), new System.Drawing.Pen(white, 2f));
                        g.Save();
                    }
                }
                return m_Snow1;
            }
        }
        private static void DrawSnow(Graphics g, System.Drawing.Brush b, System.Drawing.Pen p)
        {
            const int a = 6;
            const int a2 = a + 2;
            const int r = 2;
            g.DrawLine(p, -a, -a, +a, +a);
            g.DrawLine(p, -a, +a, +a, -a);
            g.DrawLine(p, -a2, 0, +a2, 0);
            g.DrawLine(p, 0, -a2, 0, +a2);
            g.FillEllipse(b, -r, -r, r * 2, r * 2);
        }

        private void ButtonStart_Click(object sender, RoutedEventArgs e)
        {
            Thread thread = new Thread(ShowImageList);

            thread.SetApartmentState(ApartmentState.STA);
            thread.IsBackground = true;
            thread.Start();
            
        }
        private void ShowImageList()
        {
            while (true)
            {
                for (int i = 0; i < imageList.Count; i++)
                {
                    this.Dispatcher.Invoke((Action)(() =>
                    {
                        ShowImageIndex(i);
                    }));
                    Thread.Sleep(100);
               }
               
            }
        }

        private void ShowImageIndex(int index)
        {
            
            if (imageList1[index].Visibility == Visibility.Visible)
            {
                imageList1[index].Visibility = Visibility.Hidden;
                imageList[index].Visibility = Visibility.Visible;
            }
            else
            {
                imageList1[index].Visibility = Visibility.Visible;
                imageList[index].Visibility = Visibility.Hidden;
            }
           
        }
    }
}

效果如下: