【WPF学習中】Bitmapにピクセル単位で描画4「円を描画」

コンピュータ
スポンサーリンク

プロジェクトの作成

PowerShellで実行。要dotnet.exe

mkdir SampleCircle
cd SampleCircle
dotnet new wpf
code .

ソースコード

<Window x:Class="SampleCircle.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:SampleCircle"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Image x:Name="image1" Stretch="None" />
    </Grid>
</Window>
using System.Diagnostics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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;

namespace SampleCircle
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        static void SetPixel(ref byte[] pixels, int width, int height, int x, int y, Color c)
        {
            int i = (x * 4) + (y * (width * 4));
            pixels[i+0] = c.B;
            pixels[i+1] = c.G;
            pixels[i+2] = c.R;
            pixels[i+3] = c.A;
        }
        static void Circle(ref WriteableBitmap bitmap, int x, int y, int r, Color c)
        {
            int width = (int)bitmap.PixelWidth;
            int height = (int)bitmap.PixelHeight;
            int pixelsSize = (width * 4) * height;
            byte[] pixels = new byte[pixelsSize];

            int stride = (width * bitmap.Format.BitsPerPixel + 7) / 8;
            bitmap.CopyPixels(pixels, stride, 0);

            int cx = 0;
            int cy = r;
            int d = 2 - 2 * r;

            SetPixel(ref pixels, width, height, cx + x, cy + y, c);
            SetPixel(ref pixels, width, height, cx + x, -cy + y, c);
            SetPixel(ref pixels, width, height, cy + x, cx + y, c);
            SetPixel(ref pixels, width, height, -cy + x, cx + y, c);

            while(true)
            {
                if (d > -cy)
                {
                    cy = cy - 1;
                    d = d + 1 - 2 * cy;
                }
                if (d <= cx)
                {
                    cx = cx + 1;
                    d = d + 1 + 2 * cx;
                }
                //Debug.WriteLine("cy{0}", cy);
                if (cy == 0) break;
                SetPixel(ref pixels, width, height, cx + x, cy + y, c);
                SetPixel(ref pixels, width, height, -cx + x, cy + y, c);
                SetPixel(ref pixels, width, height, -cx + x, -cy + y, c);
                SetPixel(ref pixels, width, height, cx + x, -cy + y, c);
            }


            bitmap.Lock();
            bitmap.WritePixels(new Int32Rect(0, 0, width, height), pixels, stride, 0, 0);
            bitmap.Unlock();
        }
        public MainWindow()
        {
            InitializeComponent();

            const int width = 256;
            const int height = 256;

            var wb = new WriteableBitmap(width, height, 75, 75, PixelFormats.Bgra32, null);        

            Circle(ref wb, 100, 100, 50, Color.FromArgb(255,0,0,255));

            image1.Source = wb;
        }
    }
}

ビルド

dotnet build

実行

dotnet run

コメント