班级有点长而且有效。 锥体旋转360度,锥形区域内的任何云都以黄色绘制。
但我现在要做的是背景图像是黑色的,只有当圆锥在云上旋转时才会将它们点亮为黄色只有当圆锥经过它们时才会移动它关闭检测到云。我的意思是只在锥体经过时才显示检测到的云。
我今天得到的是原始图像,当锥体在云层上移动时,它会变成黄色:
此屏幕截图显示了当云锥在云层上时会发生什么。
这个屏幕截图显示了当锥体没有覆盖任何云时:
现在我要做的是在我称为变量的类中显示原始图像:bmpWithClouds
我需要bmpWithClouds来扫描云,但在它之后我想使用512,512分辨率的空黑图像,并且只有当锥体经过云/ s时才能显示它,然后以黄色显示它们。
然后我想添加自己的点(像素=云)使它们在黑色图像中随机移动,当锥体经过它们以显示它们时。
这就是我在form1构造函数中使用DopplerRadar类的方法:
DopplerRadar dr = new DopplerRadar();
dr.pb1 = pictureBox1;
dr.Init();
这是DopplerRadar类有点长:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.IO;
using System.Drawing;
using System.Diagnostics;
namespace mws
{
class DopplerRadar
{
[DllImport("msvcrt.dll", EntryPoint = "memset", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
public static extern IntPtr MemSet(IntPtr dest, int c, int count);
private System.Windows.Forms.Timer timer1;
private Stream mymem;
private Bitmap ConvertedBmp;
private Device D3Ddev = null;
private PresentParameters D3Dpp = null;
private DisplayMode DispMode;
private Sprite D3Dsprite = null;
private Texture backTexture = null;
private Texture scannedCloudsTexture = null;
private byte[] argbValuesOfTransparentTexture;
private float distanceFromCenterPixels;
private float distanceFromCenterKm = 200F;
private List<Point> detectedPoints;
private float[] angleArray, distanceArray;
private double angleCalculation, distance;
private Bitmap bmpnew = new Bitmap(512, 512);
private int bytes = 2048 * 512;
public System.Windows.Forms.PictureBox pb1;
public void Init()
{
timer1 = new System.Windows.Forms.Timer();
timer1.Interval = 10;
timer1.Enabled = false;
timer1.Tick += Timer1_Tick;
ConvertedBmp = ConvertTo24(@"c:\temp\anim3.gif");
mymem = ToStream(ConvertedBmp, ImageFormat.Bmp);
distanceFromCenterPixels = (float)(/*183d*/ ((double)200 / 1.09289617486) * (double)distanceFromCenterKm / 200d);
argbValuesOfTransparentTexture = new byte[bytes];
InitializeDirectX(pb1);
FindPoints();
//initialize angleArray
angleArray = new float[detectedPoints.Count];
distanceArray = new float[detectedPoints.Count];
for (int i = 0; i < detectedPoints.Count; i++)
{
CalculateAngleAndDistance(detectedPoints[i].X, detectedPoints[i].Y, out angleCalculation, out distance);
angleArray[i] = (float)angleCalculation;
distanceArray[i] = (float)distance;
}
timer1.Enabled = true;
}
static float angleF_ = 0.0F;
private void Timer1_Tick(object sender, EventArgs e)
{
if (angleF_ > 360F)
{
angleF_ -= 360F;
}
ReturnTexture(scannedCloudsTexture, detectedPoints, angleArray, angleF_, bmpnew);
DisplayOnScreen(angleF_);
// To change direction to change += to -=
// To change speed to raise the value 1.0d
angleF_ += 1.0F;
}
private Bitmap ConvertTo24(string inputFileName)
{
Stopwatch sw = new Stopwatch();
sw = Stopwatch.StartNew();
Bitmap bmpIn = (Bitmap)Bitmap.FromFile(inputFileName);
Bitmap converted = new Bitmap(bmpIn.Width, bmpIn.Height, PixelFormat.Format24bppRgb);
using (Graphics g = Graphics.FromImage(converted))
{
// Prevent DPI conversion
g.PageUnit = GraphicsUnit.Pixel;
// Draw the image
g.DrawImageUnscaled(bmpIn, 0, 0);
}
//converted.Save(outputFileName, ImageFormat.Bmp);
sw.Stop();
return converted;
}
public static Stream ToStream(Image image, ImageFormat formaw)
{
var stream = new MemoryStream();
image.Save(stream, formaw);
stream.Position = 0;
return stream;
}
public Boolean InitializeDirectX(System.Windows.Forms.PictureBox pb1)
{
DispMode = Manager.Adapters[Manager.Adapters.Default.Adapter].CurrentDisplayMode;
D3Dpp = new PresentParameters();
D3Dpp.BackBufferFormat = DispMode.Format;
D3Dpp.PresentFlag = PresentFlag.LockableBackBuffer;
D3Dpp.SwapEffect = SwapEffect.Discard;
D3Dpp.PresentationInterval = PresentInterval.One; //wait for vertical sync. Synchronizes the painting with
//monitor refresh rate for smoooth animation
D3Dpp.Windowed = true; //the application has borders
try
{
D3Ddev = new Device(Manager.Adapters.Default.Adapter, DeviceType.Hardware, pb1.Handle,
CreateFlags.SoftwareVertexProcessing, D3Dpp);
//D3Ddev.VertexFormat = CustomVertex.PositionColored.Format;
D3Ddev.RenderState.Lighting = false;
D3Ddev.RenderState.CullMode = Cull.CounterClockwise;
//load imagesBmp to panelTexture
//panelTexture = Texture.FromBitmap(D3Ddev, imagesBmp, Usage.Dynamic, Pool.Default)
backTexture = TextureLoader.FromStream(D3Ddev, mymem);
//scannerTexture = TextureLoader.FromFile(D3Ddev, @"D:\Buttons\Radar\radar.png");
scannedCloudsTexture = new Texture(D3Ddev, 512, 512, 1, Usage.Dynamic, Format.A8R8G8B8, Pool.Default);
//sprite is used to draw the texture
D3Dsprite = new Sprite(D3Ddev);
return true;
}
catch
{
return false;
}
}
Bitmap bmpn;
float angle = 0;
private void DisplayOnScreen(float angleF)
{
if (angle < 360)
{
bmpn = new Bitmap(512, 512);
angle++;
}
else
{
angle = 361;
}
Surface backbuffer;
Brush myBrush = new SolidBrush(Color.FromArgb(110, 0, 255, 0)); //semi transparent color to draw the rotating cone
Graphics g;
//clear the backbuffer with Color.FromArgb(56, 56, 56). This is the double buffer mechanism. Drawing to offscreen
//backbuffer and in the end flipping it to main one which is our panelContainer
D3Ddev.Clear(ClearFlags.Target, Color.FromArgb(56, 56, 56), 1, 0);
D3Ddev.BeginScene();
//Draw Sprites
//////////////////////////////////////////////////////
D3Dsprite.Begin(SpriteFlags.AlphaBlend);
// bitmap with clouds
D3Dsprite.Draw2D(backTexture, new PointF(0, 0), 0F, new PointF(0F, 0F), Color.White);
//the part of clouds that are inside the cone
D3Dsprite.Draw2D(scannedCloudsTexture, new PointF(0F, 0F), 0F, new PointF(0F, 0F), Color.White);
//rotate cone
//D3Dsprite.Draw2D(scannerTexture, new PointF(104.5F, 0F), angle, new PointF(256F, 255F), Color.White);
D3Dsprite.Flush();
D3Dsprite.End();
//////////////////////////////////////////////////////
//Draw the cone.
using (backbuffer = D3Ddev.GetBackBuffer(0, 0, BackBufferType.Mono))
{
using (g = backbuffer.GetGraphics())
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.FillPie(myBrush, 256F - distanceFromCenterPixels, 255F - distanceFromCenterPixels,
distanceFromCenterPixels * 2F, distanceFromCenterPixels * 2F, angleF - 23F, 46F);
if (angle <= 360)
{
}
}
}
D3Ddev.EndScene();
D3Ddev.Present(); //performs the flipping
}
private void CalculateAngleAndDistance(int x, int y, out double angle, out double distance)
{
Double dbl = -1.0d;
Point center = new Point(256, 255);
distance = Math.Sqrt((double)((center.Y - y) * (center.Y - y) + (center.X - x) * (center.X - x)));
if (y == center.Y && x > center.X)
{
dbl = 0d;
angle = dbl;
return;
}
else if (x == center.X && y > center.Y)
{
dbl = 90d;
angle = dbl;
return;
}
else if (y == center.Y && x < center.X)
{
dbl = 180d;
angle = dbl;
return;
}
else if (x == center.X && y < center.Y)
{
dbl = 279d;
angle = dbl;
return;
}
else if (x == center.X && y == center.Y)
{
angle = dbl;
return;
}
if (x > center.X && y > center.Y) //1
{
dbl = Math.Atan(((double)y - (double)center.Y) / ((double)x - (double)center.X));
dbl = 180d * dbl / Math.PI;
}
else if (x < center.X && y > center.Y) //2
{
dbl = Math.Atan(((double)y - (double)center.Y) / ((double)center.X - (double)x));
dbl = 180d * dbl / Math.PI;
dbl = 180d - dbl;
}
else if (x < center.X && y < center.Y) //3
{
dbl = Math.Atan(((double)center.Y - (double)y) / ((double)center.X - (double)x));
dbl = 180d * dbl / Math.PI;
dbl += 180d;
}
else //4
{
dbl = Math.Atan(((double)center.Y - (double)y) / ((double)x - (double)center.X));
dbl = 180d * dbl / Math.PI;
dbl = 360d - dbl;
}
angle = dbl;
}
private void ReturnTexture(Texture texture_take, List<Point> lstPnt, float[] anglArr, float angle, Bitmap bmpNew)
{
int i, j, stride = 2048;
float angleBefore, angleAfter;
GraphicsStream textureStream;
Boolean bl = false;
if (bmpNew.Width != 512 && bmpNew.Height != 512)
throw new Exception("Bitmaps must be of same size.");
//sets texture to complete transparent
unsafe
{
fixed (byte* p = argbValuesOfTransparentTexture)
{
MemSet((IntPtr)p, 0x0, argbValuesOfTransparentTexture.Length);
}
}
angleAfter = angle + 23F;
if (angleAfter >= 360F)
{
angleAfter -= 360F;
}
angleBefore = angleAfter - 46;
if (angleBefore < 0F)
{
angleBefore += 360F;
bl = true;
}
BitmapData bmD = bmpNew.LockBits(new Rectangle(0, 0, bmpNew.Width, bmpNew.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
unsafe
{
byte* p = (byte*)bmD.Scan0.ToPointer();
//checks all points and draws yellow only those who are inside the cone
for (i = 0; i < lstPnt.Count - 1; i++)
{
if (anglArr[i] == -1F)
{
continue;
}
if (bl == true)
{
if (anglArr[i] <= angleAfter || anglArr[i] >= angleBefore) //if point angle is inside cone. Cone angle is 46 degrees
{
if (distanceArray[i] <= distanceFromCenterPixels)
{
j = lstPnt[i].Y * stride + lstPnt[i].X * 4;
//yellow
argbValuesOfTransparentTexture[j + 0] = (byte)0;
argbValuesOfTransparentTexture[j + 1] = (byte)255;
argbValuesOfTransparentTexture[j + 2] = (byte)255;
argbValuesOfTransparentTexture[j + 3] = (byte)255;
p[j] = (byte)0;
p[j + 1] = (byte)0;
p[j + 2] = (byte)255;
p[j + 3] = (byte)255;
}
}
}
else
{
if (anglArr[i] <= angleAfter && anglArr[i] >= angleBefore) //if point angle is inside cone. Cone angle is 46 degrees
{
if (distanceArray[i] <= distanceFromCenterPixels)
{
j = lstPnt[i].Y * stride + lstPnt[i].X * 4;
//yellow
argbValuesOfTransparentTexture[j + 0] = (byte)0;
argbValuesOfTransparentTexture[j + 1] = (byte)255;
argbValuesOfTransparentTexture[j + 2] = (byte)255;
argbValuesOfTransparentTexture[j + 3] = (byte)255;
p[j] = (byte)0;
p[j + 1] = (byte)0;
p[j + 2] = (byte)255;
p[j + 3] = (byte)255;
}
}
}
}
}
//if (angle <= 360)
// pictureBox1.Image.Save(@"c:\coneimages\" + angle + ".gif");
bmpNew.UnlockBits(bmD);
{
using (textureStream = texture_take.LockRectangle(0, LockFlags.None))
{
textureStream.Write(argbValuesOfTransparentTexture);
texture_take.UnlockRectangle(0);
}
//if (angle <= 360)
// pictureBox1.Image.Save(@"c:\coneimages\" + angle + ".gif");
}
}
private void FindPoints()
{
//Bitmap bmptest;
GraphicsPath gp = new GraphicsPath();
int x, y, p, j, wdthHght;
int bytes;
//byte error_ = 5;
byte[] rgbValuesWithClouds;
byte[] rgbValuesWithoutClouds;
IntPtr ptr;
Rectangle rect;
BitmapData bitmap_Data;
Bitmap bmpWithClouds; //No memory is allocated
Bitmap bmpWithoutClouds; //No memory is allocated
gp.AddEllipse(new RectangleF(73, 72, 367, 367));
//gp.CloseFigure();
//using the using statement, bmpWithClouds bitmap is automatically disposed at the end of statement. No memory leaks :)
using (bmpWithClouds = new Bitmap(mymem))//@"D:\MyWeatherStation-Images-And-Icons\radartobmp.bmp")) //24 bit bitmap
{
rect = new Rectangle(0, 0, bmpWithClouds.Width, bmpWithClouds.Height);
wdthHght = bmpWithClouds.Width;
//Lock bitmap to copy its color information fast
bitmap_Data = bmpWithClouds.LockBits(rect, ImageLockMode.ReadWrite, bmpWithClouds.PixelFormat);
ptr = bitmap_Data.Scan0;
bytes = bitmap_Data.Stride * bmpWithClouds.Height;
rgbValuesWithClouds = new byte[bytes];
//copy color information to rgbValues array
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValuesWithClouds, 0, bytes);
//we are done copying so unlock bitmap. We dont need it anymore
bmpWithClouds.UnlockBits(bitmap_Data);
}
//using the using statement, bmpWithClouds bitmap is automatically disposed at the end of statement. No memory leaks :)
using (bmpWithoutClouds = new Bitmap(
@"D:\C-Sharp\Download File\Downloading-File-Project-Version-012\Downloading File\bin\x86\Release\WithoutClouds.bmp"))//su + "\\WithoutClouds.bmp")) //24 bit bitmap
{
rect = new Rectangle(0, 0, bmpWithoutClouds.Width, bmpWithoutClouds.Height);
//Lock bitmap to copy its color information fast
bitmap_Data = bmpWithoutClouds.LockBits(rect, ImageLockMode.ReadWrite, bmpWithoutClouds.PixelFormat);
ptr = bitmap_Data.Scan0;
bytes = bitmap_Data.Stride * bmpWithoutClouds.Height;
rgbValuesWithoutClouds = new byte[bytes];
//copy color information to rgbValues array
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValuesWithoutClouds, 0, bytes);
//we are done copying so unlock bitmap. We dont need it anymore
bmpWithoutClouds.UnlockBits(bitmap_Data);
}
// Each position in these arrays, rgbValuesWithoutClouds and rgbValuesWithClouds, corresponds a color. eg
// First pixel Second pixel Third pixel Forth pixel .... // bitmaps
// B G R B G R B G R B G R .... // rgbValues arrays
//bmptest = new Bitmap(512, 512);
detectedPoints = new List<Point>();
for (y = 0; y < wdthHght; y++)
{
j = 0;
for (x = 0; x < wdthHght; x++)
{
p = y * wdthHght * 3 + j;
if (rgbValuesWithClouds[p] != rgbValuesWithoutClouds[p])
{
detectedPoints.Add(new Point(x, y));
//bmptest.SetPixel(x, y, Color.Red);
}
j += 3;
}
}
}
}
}