using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Doppler_Radar
{
public partial class Form1 : Form
{
int myPiePercent = 15;
float distanceFromCenterPixels;
float distanceFromCenterKm = 200F;
public Form1()
{
InitializeComponent();
pictureBox1.Image = Image.FromFile(@"D:\New folder (4)\Weather Radar\WithClouds.bmp");
timer1.Enabled = true;
distanceFromCenterPixels = (float)(183d * (double)distanceFromCenterKm / 200d);
pictureBox1.Image = CalcDifference(new Bitmap(pictureBox1.Image),
new Bitmap(@"D:\New folder (4)\Weather Radar\WithoutClouds.bmp"));
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
DrawPieOnPicturebox(e.Graphics);
}
public void DrawPieOnPicturebox(Graphics myPieGraphic)
{
Color myPieColors = Color.FromArgb(150, Color.LightGreen);
Size myPieSize = new Size((int)distanceFromCenterPixels, (int)distanceFromCenterPixels);
Point myPieLocation = new Point((pictureBox1.Width - myPieSize.Width) / 2, (pictureBox1.Height - myPieSize.Height) / 2);
DrawMyPie(myPiePercent, myPieColors, myPieGraphic, myPieLocation, myPieSize);
}
public void DrawMyPie(int myPiePerecent, Color myPieColor, Graphics myPieGraphic, Point
myPieLocation, Size myPieSize)
{
using (SolidBrush brush = new SolidBrush(myPieColor))
{
myPieGraphic.FillPie(brush, new Rectangle(myPieLocation, myPieSize), Convert.ToSingle(myPiePerecent * 360 / 100), Convert.ToSingle(15 * 360 / 100));
}
}
private void timer1_Tick(object sender, EventArgs e)
{
myPiePercent++;
pictureBox1.Invalidate();
}
public Bitmap CalcDifference(Bitmap bmp1, Bitmap bmp2)
{
Rectangle rect = new Rectangle(0, 0, bmp1.Width, bmp1.Height);
BitmapData bitmapdata = bmp1.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
IntPtr source = bitmapdata.Scan0;
BitmapData data2 = bmp2.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
IntPtr ptr2 = data2.Scan0;
int length = (bmp1.Width * bmp1.Height) * 4;
byte[] destination = new byte[length];
byte[] buffer2 = new byte[length];
Marshal.Copy(source, destination, 0, length);
Marshal.Copy(ptr2, buffer2, 0, length);
for (int i = 0; i < length; i += 4)
{
if (((destination[i] == buffer2[i]) && (destination[i + 1] == buffer2[i + 1])) && (destination[i + 2] == buffer2[i + 2]))
{
destination[i] = 0xff;
destination[i + 1] = 0xff;
destination[i + 2] = 0xff;
destination[i + 3] = 0;
}
else
{
destination[i] = 0;
destination[i + 1] = 255;
destination[i + 2] = 255;
}
}
Marshal.Copy(destination, 0, source, length);
bmp1.UnlockBits(bitmapdata);
bmp2.UnlockBits(data2);
return bmp1;
}
}
}
因为我在构造函数中调用了CalcDifference方法,所以始终将差分像素着色为黄色。但我想要的是,只有当旋转饼位于差分像素之上/之上时,才对饼之下的差分像素着色,而不是对所有差分像素着色。
左侧是使用CalcDifference方法对差分像素进行着色时。右侧是原始图像。
目标是产生多普勒雷达效应,当饼在云上方旋转时探测云。
1条答案
按热度按时间kyxcudwk1#
是的,你可以使用一个小技巧来改变馅饼下面的云的颜色,跳过其他的。
CalcDifference
方法并加快速度,只需从每个图像中获取要处理的饼图区域,图像的其余部分不变,也不需要遍历该区域的数据。CalcDifference
方法,并更改该区域中云的颜色。注意,如果需要的话,我已经更改了将原始图像转换为32bppArgb
图像的方法,以便您可以传递LockBits
支持的不同格式的图像进行处理。PictureBox
的.Image
属性。PictureBox.Paint
事件并创建一个GraphicsPath
对象,添加饼并将其传递给Graphics.SetClip
方法。绘制黄色云彩图像,然后重置剪辑(Graphics.ResetClip
)绘制饼。摘自您之前针对本演示提出的问题。