I have a little problem in my Unity work, I'm trying to get the images from a Webcam texture, and I'll keep it in a byte []. the problem comes when I show the image, which is not seen correctly, it looks like some type of grid mesh. I think the problem is in the for I use to pass the pixels. I hope you can help me.
void Update()
{
//texto.text = texto.text + width +" / "+ height + " / " + ini.ToString()+ " mal: "+ testo().ToString()+ " SizeIMG: "+ imgData.Length + " NUEVO: "+ nuevo +"\n";
imgData = null;
imgData = new byte[width * height * 3];
resultado = null;
resultado = new byte[width * height * 3];
color = webcam.GetPixels32();
for (int i = 0; i < color.Length; i += 3)
{
imgData[(i * 3)] = color[i].r;
imgData[(i * 3) + 1] = color[i].g;
imgData[(i * 3) + 2] = color[i].b;
}
color = null;
//video(imgData, resultado);
//ProcessFrame(imgData, resultado, 0, 0, 0,0, nuevo);
nuevo = false;
textura2 = new Texture2D(width, height, TextureFormat.RGB24, false);
textura2.LoadRawTextureData(imgData);
textura2.Apply();
//Left IMAGE
renderer.material.mainTexture = textura2;
textura2 = null;
RightImage.GetComponent<Renderer>().material.mainTexture = webcam;
if (kont == 30)
{
texto.text = "";
kont = 0;
}
kont++;
Resources.UnloadUnusedAssets();
}
I think the issue is how your indexing into your imgData array. You're incrementing i by three in addition to multiplying by 3.
int bytesPerPixel = 3;
const int indexR = 0;
const int indexG = 1;
const int indexB = 2;
for(var i = 0; i < color.Length; i++)
{
imgData[(i * bytesPerPixel) + indexR] = color[i].r;
imgData[(i * bytesPerPixel) + indexG] = color[i].g;
imgData[(i * bytesPerPixel) + indexB] = color[i].b;
}
Related
When I run this code
Bitmap im = new Bitmap(600, 600, PixelFormat.Format16bppGrayScale);
int height = im.Height;
int width = im.Width;
Point p1 = new Point(0, 0);
Point p2 = new Point(im.Size.Width, 0);
Point p3 = new Point(im.Width / 2, im.Height);
Random r = new Random();
Point p = new Point(r.Next(0, im.Size.Width), r.Next(0, im.Size.Height));
BitmapData data = im.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format16bppGrayScale);
const int stride = 2;
int wsrtide = data.Stride;
unsafe
{
IntPtr osc0 = data.Scan0;
ushort* sc0 = (ushort*)data.Scan0;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
*sc0 = 0;
sc0 += 1;
}
}
for (long i = 0; i < width * height; i++)
{
if (i % 1_000_000 == 0)
{
Console.WriteLine(i);
}
var ran = r.Next(0, 3);
Point tp;
switch (ran)
{
case 0:
tp = new Point((p1.X + p.X) / 2, (p1.Y + p.Y) / 2);
sc0 = (ushort*)((int)osc0 + (wsrtide * tp.Y + (tp.X * stride)));
*sc0 = ushort.MaxValue;
p = tp;
break;
case 1:
tp = new Point((p2.X + p.X) / 2, (p2.Y + p.Y) / 2);
sc0 = (ushort*)((int)osc0 + (wsrtide * tp.Y + (tp.X * stride)));
*sc0 = ushort.MaxValue;
p = tp;
break;
case 2:
tp = new Point((p3.X + p.X) / 2, (p3.Y + p.Y) / 2);
sc0 = (ushort*)((int)osc0 + (wsrtide * tp.Y + (tp.X * stride)));
*sc0 = ushort.MaxValue;
p = tp;
break;
}
}
im.UnlockBits(data);
im.Save(Environment.CurrentDirectory + "\\img.png");
im.Dispose();
It throws where I save the bitmap
System.Runtime.InteropServices.ExternalException: A generic error
occurred in GDI+.`
I am almost certain that this isn't caused by file permissions, when I give the program admin permission and delete the image to reset permissions it still throws. I can confirm that this code swapped with BitmapSetPixel() on RGB works.
My suspicion is that I'm messing up the pointers, but I'm not really sure. Also, curiously enough, it makes empty png files even though it throws.
The purpose of this code is to generate a Sierpinski triangle using the chaos game method.
Your problem is the Format16bppGrayScale i don't think the GDI supports it very well.
Basically if you just create the Bitmap in Format16bppGrayScale, and save it with nothing else, it still gives the error.
I have taken the liberty to rewrite your method Format32bppPArgb
private unsafe static void Main(string[] args)
{
var height = 600;
var width = 600;
var p1 = new Point(0, 0);
var p2 = new Point(width, 0);
var p3 = new Point(width / 2, height);
var r = new Random();
var p = new Point(r.Next(0, width), r.Next(0, width));
using (var im = new Bitmap(width, height, PixelFormat.Format32bppPArgb))
{
var data = im.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb);
var sc0 = (int*)data.Scan0;
var pLen = sc0 + height * width;
var black = Color.Black.ToArgb();
var white = Color.White.ToArgb();
for (var pI = sc0; pI < pLen; pI++)
*pI = black;
for (long i = 0; i < width * height; i++)
{
Point tp;
switch (r.Next(0, 3))
{
case 0:
tp = new Point((p1.X + p.X) / 2, (p1.Y + p.Y) / 2);
*(sc0 + tp.Y + tp.X * width) = white;
p = tp;
break;
case 1:
tp = new Point((p2.X + p.X) / 2, (p2.Y + p.Y) / 2);
*(sc0 + tp.Y + tp.X * width) = white;
p = tp;
break;
case 2:
tp = new Point((p3.X + p.X) / 2, (p3.Y + p.Y) / 2);
*(sc0 + tp.Y + tp.X * width) = white;
p = tp;
break;
}
}
im.UnlockBits(data);
im.Save(#"D:\img.png", ImageFormat.Png);
}
}
Result
You can convert it after the fact if you want, add pepper and salt to taste
Also if you get rid of all the points and cache the colors this will be a bit faster
I have my image cropping app based on:
http://www.c-sharpcorner.com/UploadFile/55275a/windowsphone-image-crop-with-rectangle/
I modified it a little bit so I can resize rectangle instead of creating new
so my whole method look like:
private async void Accept_Click(object sender, EventArgs e)
{
WriteableBitmap wb = new WriteableBitmap(image);
double originalImageWidth = wb.PixelWidth;
double originalImageHeight = wb.PixelHeight;
double displayedWidth = image1.ActualWidth;
double displayedHeight = image1.ActualHeight;
double widthRatio = originalImageWidth / displayedWidth;
double heightRatio = originalImageHeight / displayedHeight;
r = (Rectangle) (from c in LayoutRoot.Children
where c.Opacity == .5 select c).First();
GeneralTransform gt = r.TransformToVisual(LayoutRoot);
Point p = gt.Transform(new Point(0, 0));
Point1 = (r.TransformToVisual(this)).Transform(new Point(0, 0));
Point2 = new Point(Point1.X + r.Width, Point1.Y + r.Height);
WriteableBitmap newImage = new WriteableBitmap(
(int) (widthRatio * Math.Abs(Point2.X - Point1.X)),
(int) (heightRatio * Math.Abs(Point2.Y - Point1.Y)));
int xoffset = (int) (((Point1.X < Point2.X) ? Point1.X : Point2.X) * widthRatio);
int yoffset = (int) (((Point1.Y < Point2.Y) ? Point1.Y : Point2.X) * heightRatio);
if (newImage.Pixels.Length > 0)
{
for (int i = 0; i < newImage.Pixels.Length; i++)
{
int x = (int) ((i % newImage.PixelWidth) + xoffset);
int y = (int) ((i / newImage.PixelWidth) + yoffset);
newImage.Pixels[i] = wb.Pixels[y * wb.PixelWidth + x];
}
using (MemoryStream ms = new MemoryStream())
{
newImage.SaveJpeg(ms, (int) newImage.PixelWidth,
(int) newImage.PixelHeight, 0, 100);
image.SetSource(ms);
}
}
else
{
}
ProgressBar pb = new ProgressBar();
pb.IsEnabled = true;
LayoutRoot.Children.Add(pb);
int idReceipt = (int) PhoneApplicationService.Current.State["paragon"];
await ReceiptsHelper.addPhotosToReceipt(image, idReceipt);
NavigationService.Navigate(new Uri("/7.0/StronaParagonu.xaml", UriKind.Relative));
}
When my image is vertical everything works fine, but when my image is horizontal I get Array Index Out Of Bounds Exception at:
newImage.Pixels[i] = wb.Pixels[y * wb.PixelWidth + x];
I don't know exactly what am I doing wrong.
Anybody can help?
EDIT:
I changed my code to:
if (wb.PixelWidth > wb.PixelHeight)
{
for (int i = 0; i < newImage.Pixels.Length; i++)
{
int x = (int)((i % newImage.PixelWidth) + xoffset);
int y = (int)((i / newImage.PixelWidth) + yoffset);
newImage.Pixels[i] = wb.Pixels[x * wb.PixelHeight + y];
}
}
else
{
for (int i = 0; i < newImage.Pixels.Length; i++)
{
int x = (int)((i % newImage.PixelWidth) + xoffset);
int y = (int)((i / newImage.PixelWidth) + yoffset);
newImage.Pixels[i] = wb.Pixels[y * wb.PixelWidth + x];
}
}
In result I've got something like this
Maybe there is some workaround in which I can flip image 90 degree?
I tried WriteableBitmapEx but it doesnt work.
First thing I see is:
int yoffset = (int) (((Point1.Y < Point2.Y) ? Point1.Y : Point2.X) * heightRatio);
I guess there should be Point2.Y?
Second thing is what #Rashed mentioned in comment:
When you want get horizontal image, you must change X and Y place: newImage.Pixels[i] = wb.Pixels[x * wb.PixelHeight + y];
But please take a note I'm really guessing here since it's late and I don't see sharp ;-)
I am trying to render a quantity of cubes like in "Minecraft" a chunk with C# + OpenTK + OpenGL 4.1.
To do that, I create a buffer with type "ElementArrayBuffer" for indices and a buffer with type "ArrayBuffer" to store the vertices.
But I think to describe it, is more difficult than examine the code.
If someone has questions please tell me.
So now the problem.
The rendering result is not that, what I want and I don't understand why and whats wrong.
If I render this I get this result:
class Chunk
{
// The size of the chunk
// One unit means one cube
public const int WIDTH = 5;
public const int HEIGHT = 5;
public const int DEPTH = 2;
private int[][][] mData;
// The attribute location the the shader program
private int mVePositionLocation;
private int mVertexArray;
private int mIndexBuffer;
private int mVertexBuffer;
private int mIndexCount;
public Chunk(int pVePositionLocation)
{
mVePositionLocation = pVePositionLocation;
GenerateData();
GenerateMesh();
}
private void GenerateData()
{
mData = new int[DEPTH][][];
for(int z = 0; z < DEPTH; z++)
{
mData[z] = new int[HEIGHT][];
for(int y = 0; y < HEIGHT; y++)
{
mData[z][y] = new int[WIDTH];
for(int x = 0; x < WIDTH; x++)
{
mData[z][y][x] = 1;
}
}
}
}
private void GenerateMesh()
{
Queue<float> vertices = new Queue<float>();
Queue<uint> indices = new Queue<uint>();
uint offset = 0;
for (int z = 0; z < DEPTH; z++)
{
for (int y = 0; y < HEIGHT; y++)
{
for (int x = 0; x < WIDTH; x++)
{
// If the value is bigger than 0 there is a cube so it should be generated
if(mData[z][y][x] > 0)
{
GenerateCube(x, y, z, offset, vertices, indices);
// Normally 36 indices offset, but for now I only generate the front face of each cube so only 6 indices
offset += 6;
}
}
}
}
// Create and fill the buffer with the indices
mIndexBuffer = GL.GenBuffer();
GL.BindBuffer(BufferTarget.ElementArrayBuffer, mIndexBuffer);
GL.BufferData<uint>(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Count * sizeof(uint)), indices.ToArray(), BufferUsageHint.StaticDraw);
mVertexArray = GL.GenVertexArray();
GL.BindVertexArray(mVertexArray);
// The buffer with the vertices
mVertexBuffer = GL.GenBuffer();
GL.BindBuffer(BufferTarget.ArrayBuffer, mVertexBuffer);
GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Count * sizeof(float)), vertices.ToArray(), BufferUsageHint.StaticDraw);
// The shader only needs the position
GL.EnableVertexAttribArray(mVePositionLocation);
GL.VertexAttribPointer(mVePositionLocation, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), 0);
// Store the index count, so I can render later
mIndexCount = indices.Count;
}
private void GenerateCube(int pX, int pY, int pZ, uint pOffset, Queue<float> pVertices, Queue<uint> pIndices)
{
// Front face vertices
pVertices.Enqueue(pX);
pVertices.Enqueue(pY);
pVertices.Enqueue(pZ + Cube.DEPTH);
pVertices.Enqueue(pX + Cube.WIDTH);
pVertices.Enqueue(pY);
pVertices.Enqueue(pZ + Cube.DEPTH);
pVertices.Enqueue(pX);
pVertices.Enqueue(pY + Cube.HEIGHT);
pVertices.Enqueue(pZ + Cube.DEPTH);
pVertices.Enqueue(pX + Cube.WIDTH);
pVertices.Enqueue(pY + Cube.HEIGHT);
pVertices.Enqueue(pZ + Cube.DEPTH);
// Front face indices
pIndices.Enqueue(pOffset + 0);
pIndices.Enqueue(pOffset + 2);
pIndices.Enqueue(pOffset + 3);
pIndices.Enqueue(pOffset + 0);
pIndices.Enqueue(pOffset + 3);
pIndices.Enqueue(pOffset + 1);
}
public void Render()
{
GL.BindBuffer(BufferTarget.ElementArrayBuffer, mIndexBuffer);
GL.BindVertexArray(mVertexArray);
GL.DrawElements(BeginMode.Triangles, mIndexCount, DrawElementsType.UnsignedInt, 0);
}
}
The shader program:
string vertexShaderSource = "#version 410\n" +
"\n" +
"uniform mat4 un_Projection; \n" +
"uniform mat4 un_Transform; \n" +
"\n" +
"layout(location = 0) in vec3 ve_Position;\n" +
"\n" +
"out vec4 fr_Color;" +
"\n" +
"void main()\n" +
"{\n" +
" fr_Color = vec4(1, 0, 0, 1);\n" +
" gl_Position = un_Projection * un_Transform * vec4(ve_Position.xyz, 1);\n" +
"}\n";
string fragmentShaderSource = "#version 410\n" +
"\n" +
"in vec4 fr_Color;\n" +
"\n" +
"out vec4 fi_Color;\n" +
"\n" +
"void main()\n" +
"{\n" +
" fi_Color = fr_Color;\n" +
"}\n";
If someone wants the full project folder:
http://www.file-upload.net/download-10301899/Project.zip.html
Ok, I found the mistake.
I should not be
// Normally 36 indices offset, but for now I only generate the front face of each cube so only 6 indices
offset += 6;
It should be
// 4 vertices a face so add 4 offset a cube
offset += 4;
i am using mapwingis and i have uploaded all the needed shape file..now i already have the data from the gps and i want to show it in my map. i had researched that i can use drawcircleex, but it does not give me the correct location and the circle is stucked in the center. heres my code:
MapWinGIS.Shapefile plane = new MapWinGIS.Shapefile();// shape 1
MapWinGIS.Shapefile roads = new MapWinGIS.Shapefile();// shape 2
MapWinGIS.Shapefile gensan = new MapWinGIS.Shapefile();// shape 3
MapWinGIS.Shapefile pois = new MapWinGIS.Shapefile();// shape 4
MapWinGIS.Shapefile pofw = new MapWinGIS.Shapefile();// shape 5
MapWinGIS.Shapefile places = new MapWinGIS.Shapefile();// shape 6
MapWinGIS.Shapefile roadsfin = new MapWinGIS.Shapefile();// shape 7
MapWinGIS.Shapefile circle = new MapWinGIS.Shapefile();// shape 8
int shape1, shape2, shape3, shape4, shape5, shape6, shape7, shape8;
public static string varname;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// layer of plane
plane.Open("C:/Users/User/Desktop/THESIS/New Folder (2)/phi/philippines/adminareasfinal.shp", null);
shape1 = axMap1.AddLayer(plane, true);
axMap1.set_ShapeLayerFillColor(shape1, (UInt32)(System.Drawing.ColorTranslator.ToOle
(System.Drawing.Color.Linen)));
axMap1.set_ShapeLayerLineColor(shape1, (UInt32)(System.Drawing.ColorTranslator.ToOle
(System.Drawing.Color.Linen)));
// layer of gensan
gensan.Open("C:/Users/User/Desktop/THESIS/New Folder (2)/gensan_southcotabato/gensan_southcotabato.shp", null);
shape2 = axMap1.AddLayer(gensan, true);
axMap1.set_ShapeLayerFillColor(shape2, (UInt32)(System.Drawing.ColorTranslator.ToOle
(System.Drawing.Color.OldLace)));
axMap1.set_ShapeLayerLineColor(shape2, (UInt32)(System.Drawing.ColorTranslator.ToOle
(System.Drawing.Color.Black)));
// layer of longitude and latitude
Single LineWidth1 = 1;
roadsfin.Open("C:/Users/User/Desktop/THESIS/New Folder (2)/phi/philippines/roadsfin.shp", null);
shape7 = axMap1.AddLayer(roadsfin, true);
axMap1.set_UDPointType(shape7, roadsfin);
axMap1.set_ShapeLayerPointSize(shape7, LineWidth1);
axMap1.set_ShapeLayerPointColor(shape7, (UInt32)(System.Drawing.ColorTranslator.ToOle
(System.Drawing.Color.Transparent)));
// layer of roads
Single LineWidth = 2;
roads.Open("C:/Users/User/Desktop/THESIS/New Folder (2)/phi/philippines/roads.shp", null);
shape3 = axMap1.AddLayer(roads, true);
axMap1.set_ShapeLayerLineWidth(shape3, LineWidth);
axMap1.set_ShapeLayerLineColor(shape3, (UInt32)(System.Drawing.ColorTranslator.ToOle
(System.Drawing.Color.White)));
//layer of pois and pofw bitmap image
Single pointsize = 1;
pois.Open("C:/Users/User/Desktop/THESIS/New Folder (2)/phi/philippines/pois.shp", null);
shape4 = axMap1.AddLayer(pois, true);
pofw.Open("C:/Users/User/Desktop/THESIS/New Folder (2)/phi/philippines/pofw.shp", null);
shape5 = axMap1.AddLayer(pofw, true);
places.Open("C:/Users/User/Desktop/THESIS/New Folder (2)/phi/philippines/places.shp", null);
shape6 = axMap1.AddLayer(places, true);
int LineWidth7 = 10;
circle.Open("C:/Users/User/Desktop/THESIS/New Folder (2)/phi/newshape/finalepoint.shp", null);
shape8 = axMap1.AddLayer(circle, true);
axMap1.set_ShapeLayerPointColor(shape8, (UInt32)(System.Drawing.ColorTranslator.ToOle
(System.Drawing.Color.Black)));
axMap1.set_ShapeLayerPointSize(shape8, LineWidth7);
string circlelabel;
double x12, y12;
for (int j = 0; j < circle.NumShapes - 1; j++)
{
circlelabel = System.Convert.ToString(roads.get_CellValue(1, j));
x12 = circle.get_Shape(j).Extents.xMin + (circle.get_Shape(j).Extents.xMax - circle.get_Shape(j).Extents.xMin) / 2;
y12 = circle.get_Shape(j).Extents.yMin + (circle.get_Shape(j).Extents.yMax - circle.get_Shape(j).Extents.yMin) / 2;
axMap1.AddLabel(shape8, circlelabel, (UInt32)(System.Drawing.ColorTranslator.ToOle
(System.Drawing.Color.Red)), x12, y12, MapWinGIS.tkHJustification.hjCenter);
}
MapWinGIS.Image poisimage = new MapWinGIS.Image();
MapWinGIS.Image pofwimage = new MapWinGIS.Image();
MapWinGIS.Image placesimage = new MapWinGIS.Image();
poisimage.Open("C:/Users/User/Desktop/bitmap/poisimage.bmp", MapWinGIS.ImageType.USE_FILE_EXTENSION, true, null);
{
this.axMap1.set_ShapeLayerPointSize(shape4, pointsize);
this.axMap1.set_ShapeLayerPointType(shape4, MapWinGIS.tkPointType.ptUserDefined);
this.axMap1.set_UDPointType(shape4, poisimage);
}
axMap1.set_LayerVisible(shape4, true);
pofwimage.Open("C:/Users/User/Desktop/bitmap/pofwimage.bmp", MapWinGIS.ImageType.USE_FILE_EXTENSION, true, null);
{
this.axMap1.set_ShapeLayerPointSize(shape5, pointsize);
this.axMap1.set_ShapeLayerPointType(shape5, MapWinGIS.tkPointType.ptUserDefined);
this.axMap1.set_UDPointType(shape5, pofwimage);
}
axMap1.set_LayerVisible(shape5, true);
placesimage.Open("C:/Users/User/Desktop/bitmap/placesimage.bmp", MapWinGIS.ImageType.USE_FILE_EXTENSION, true, null);
{
this.axMap1.set_ShapeLayerPointSize(shape6, pointsize);
this.axMap1.set_ShapeLayerPointType(shape6, MapWinGIS.tkPointType.ptUserDefined);
this.axMap1.set_UDPointType(shape6, placesimage);
}
axMap1.set_LayerVisible(shape6, true);
// the following are the codes to show the names of Roads
string myLabel;
double x, y;
for (int i = 0; i < roads.NumShapes - 1; i++)
{
myLabel = System.Convert.ToString(roads.get_CellValue(4, i));
x = roads.get_Shape(i).Extents.xMin + (roads.get_Shape(i).Extents.xMax - roads.get_Shape(i).Extents.xMin) / 2;
y = roads.get_Shape(i).Extents.yMin + (roads.get_Shape(i).Extents.yMax - roads.get_Shape(i).Extents.yMin) / 2;
axMap1.AddLabel(shape2, myLabel, (UInt32)(System.Drawing.ColorTranslator.ToOle
(System.Drawing.Color.Black)), x, y, MapWinGIS.tkHJustification.hjCenter);
}
// the following are the codes to show the names of pois
string poislabel;
double pois1, pois2;
int handle = axMap1.NewDrawing(MapWinGIS.tkDrawReferenceList.dlScreenReferencedList);
for (int ps = 0; ps < pois.NumShapes - 1; ps++)
{
poislabel = System.Convert.ToString(pois.get_CellValue(4, ps));
pois1 = pois.get_Shape(ps).Extents.xMin + (pois.get_Shape(ps).Extents.xMax - pois.get_Shape(ps).Extents.xMin) / 2;
pois2 = pois.get_Shape(ps).Extents.yMin + (pois.get_Shape(ps).Extents.yMax - pois.get_Shape(ps).Extents.yMin) / 2;
double width = pois.get_Shape(ps).Extents.xMin + (pois.get_Shape(ps).Extents.xMax - pois.get_Shape(ps).Extents.xMin) / 2;
double height = pois.get_Shape(ps).Extents.yMin + (pois.get_Shape(ps).Extents.yMax - pois.get_Shape(ps).Extents.yMin) / 2;
axMap1.DrawCircleEx(handle, width, height, 5.0, 255, true);
axMap1.AddLabel(shape4, poislabel, (UInt32)(System.Drawing.ColorTranslator.ToOle
(System.Drawing.Color.Black)), pois1, pois2, MapWinGIS.tkHJustification.hjCenter);
}
// the following is to display the latitude
string latitude;// longitude;
double latx1, latx2;
for (int counter = 0; counter < roadsfin.NumShapes - 1; counter++)
{
latitude = System.Convert.ToString(roadsfin.get_CellValue(1, counter));
latx1 = roadsfin.get_Shape(counter).Extents.xMin + (roadsfin.get_Shape(counter).Extents.xMax - roadsfin.get_Shape(counter).Extents.xMin) / 2;
latx2 = roadsfin.get_Shape(counter).Extents.yMin + (roadsfin.get_Shape(counter).Extents.yMax - roadsfin.get_Shape(counter).Extents.yMin) / 2;
axMap1.AddLabel(shape7, latitude, (UInt32)(System.Drawing.ColorTranslator.ToOle
(System.Drawing.Color.Black)), latx1, latx2, MapWinGIS.tkHJustification.hjCenter);
}
// sample displaying of location
// the following are the codes to show the names of pofw
string pofwlabel;
double pofw1, pofw2;
for (int pf = 0; pf < pofw.NumShapes - 1; pf++)
{
pofwlabel = System.Convert.ToString(pofw.get_CellValue(4, pf));
pofw1 = pofw.get_Shape(pf).Extents.xMin + (pofw.get_Shape(pf).Extents.xMax - pofw.get_Shape(pf).Extents.xMin) / 2;
pofw2 = pofw.get_Shape(pf).Extents.yMin + (pofw.get_Shape(pf).Extents.yMax - pofw.get_Shape(pf).Extents.yMin) / 2;
axMap1.AddLabel(shape5, pofwlabel, (UInt32)(System.Drawing.ColorTranslator.ToOle
(System.Drawing.Color.Black)), pofw1, pofw2, MapWinGIS.tkHJustification.hjCenter);
}
// the following are the codes to show the names of places
string placeslabel;
double places1, places2;
for (int pl = 0; pl < places.NumShapes - 1; pl++)
{
placeslabel = System.Convert.ToString(places.get_CellValue(4, pl));
places1 = places.get_Shape(pl).Extents.xMin + (places.get_Shape(pl).Extents.xMax - places.get_Shape(pl).Extents.xMin) / 2;
places2 = places.get_Shape(pl).Extents.yMin + (places.get_Shape(pl).Extents.yMax - places.get_Shape(pl).Extents.yMin) / 2;
axMap1.AddLabel(shape6, placeslabel, (UInt32)(System.Drawing.ColorTranslator.ToOle
(System.Drawing.Color.Black)), places1, places2, MapWinGIS.tkHJustification.hjCenter);
}
double x_etchos = 125.141;
double y_etchos = 6.117;
double x_leche = 125.141;
double y_leche = 6.117;
// MapWinGIS.Extents ext = axMap1.Extents as MapWinGIS.Extents;
double ewanko;
for (int test1 = 0; test1 < roadsfin.NumShapes; test1++)
{
ewanko = System.Convert.ToDouble(roads.get_CellValue(4, test1));
if (x_etchos > roadsfin.get_Shape(test1).Extents.xMin && x_etchos < roadsfin.get_Shape(test1).Extents.xMax && y_etchos > roadsfin.get_Shape(test1).Extents.yMin && y_etchos < roadsfin.get_Shape(test1).Extents.yMax)
{
double width = roadsfin.get_Shape(test1).Extents.xMin + (roadsfin.get_Shape(test1).Extents.xMax - roadsfin.get_Shape(test1).Extents.xMin) / 2;
double height = roadsfin.get_Shape(test1).Extents.yMin + (roadsfin.get_Shape(test1).Extents.yMax - roadsfin.get_Shape(test1).Extents.yMin) / 2;
MessageBox.Show("width and height: " + width + " " + height);
//MessageBox.Show("x and y: " + ext.xMax + " <<max_X-min_X>> " + ext.xMin + " " + ext.yMax + " <<max_Y-min_X>> " + ext.yMin);
ext.SetBounds(x_etchos - width, y_etchos - height, 0.0, x_etchos + width, y_etchos + height, 0.0);
Application.DoEvents();
axMap1.ProjToPixel(x_etchos, y_etchos, ref x_leche, ref y_leche);
axMap1.DrawCircleEx(handle, x_leche, y_leche, 5.0, 255, true);
}
}
The problem with this code is you are only calculating position and placement once. On load. You need to re-write the form class to handle zoom/pan events and re-calculate the shape positions and size.
Programs usually contain more than one function. the application.doEvents will process events in the queue but you aren't updating the shapes based on the events.
TIP
also things like
pofw1 = pofw.get_Shape(pf).Extents.xMin + (pofw.get_Shape(pf).Extents.xMax - pofw.get_Shape(pf).Extents.xMin) / 2;
pofw2 = pofw.get_Shape(pf).Extents.yMin + (pofw.get_Shape(pf).Extents.yMax - pofw.get_Shape(pf).Extents.yMin) / 2;
are easily put in a function since you call it multiple times in that function.
private Point getCenter( Extents ext ) {
Point p;
p.X = ext.xMin + (ext.xMax - ext.xMin)/2.0;
p.Y = ext.yMin + (ext.yMax - ext.yMin)/2.0;
return p;
}
called by
Point pofwPoint = getCenter(pofw.get_Shape(pf).Extents);
I found some great code here on SO and have implemented it in my app and although it is "working", the blur effect is not strong enough to actually realise (without focusing very hard on it) that it has actually blurred anything.
The code is (quite long, sorry):
Bitmap screenshot = null;
void BlurForm()
{
/*
The best time (I assume) is to change the blur when the user as left the window,
as opposed to doing it when they want to open the window, since this may be a
little intensive.
*/
screenshot = null;
blurred.Image = null; // This variable is the PictureBox that's on the Form
screenshot = Screenshot.TakeSnapshot(this);
BitmapFilter.GaussianBlur(screenshot, 4);
blurred.Image = screenshot;
blurred.SendToBack();
}
public class ConvMatrix
{
public int TopLeft = 0, TopMid = 0, TopRight = 0;
public int MidLeft = 0, Pixel = 1, MidRight = 0;
public int BottomLeft = 0, BottomMid = 0, BottomRight = 0;
public int Factor = 1;
public int Offset = 0;
public void SetAll(int nVal)
{
TopLeft = TopMid = TopRight = MidLeft = Pixel = MidRight = BottomLeft = BottomMid = BottomRight = nVal;
}
}
public class BitmapFilter
{
private static bool Conv3x3(Bitmap b, ConvMatrix m)
{
// Avoid divide by zero errors
if (0 == m.Factor) return false;
Bitmap bSrc = (Bitmap)b.Clone();
// GDI+ still lies to us - the return format is BGR, NOT RGB.
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
int stride2 = stride * 2;
System.IntPtr Scan0 = bmData.Scan0;
System.IntPtr SrcScan0 = bmSrc.Scan0;
unsafe
{
byte* p = (byte*)(void*)Scan0;
byte* pSrc = (byte*)(void*)SrcScan0;
int nOffset = stride + 6 - b.Width * 3;
int nWidth = b.Width - 2;
int nHeight = b.Height - 2;
int nPixel;
for (int y = 0; y < nHeight; ++y)
{
for (int x = 0; x < nWidth; ++x)
{
nPixel = ((((pSrc[2] * m.TopLeft) + (pSrc[5] * m.TopMid) + (pSrc[8] * m.TopRight) +
(pSrc[2 + stride] * m.MidLeft) + (pSrc[5 + stride] * m.Pixel) + (pSrc[8 + stride] * m.MidRight) +
(pSrc[2 + stride2] * m.BottomLeft) + (pSrc[5 + stride2] * m.BottomMid) + (pSrc[8 + stride2] * m.BottomRight)) / m.Factor) + m.Offset);
if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;
p[5 + stride] = (byte)nPixel;
nPixel = ((((pSrc[1] * m.TopLeft) + (pSrc[4] * m.TopMid) + (pSrc[7] * m.TopRight) +
(pSrc[1 + stride] * m.MidLeft) + (pSrc[4 + stride] * m.Pixel) + (pSrc[7 + stride] * m.MidRight) +
(pSrc[1 + stride2] * m.BottomLeft) + (pSrc[4 + stride2] * m.BottomMid) + (pSrc[7 + stride2] * m.BottomRight)) / m.Factor) + m.Offset);
if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;
p[4 + stride] = (byte)nPixel;
nPixel = ((((pSrc[0] * m.TopLeft) + (pSrc[3] * m.TopMid) + (pSrc[6] * m.TopRight) +
(pSrc[0 + stride] * m.MidLeft) + (pSrc[3 + stride] * m.Pixel) + (pSrc[6 + stride] * m.MidRight) +
(pSrc[0 + stride2] * m.BottomLeft) + (pSrc[3 + stride2] * m.BottomMid) + (pSrc[6 + stride2] * m.BottomRight)) / m.Factor) + m.Offset);
if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;
p[3 + stride] = (byte)nPixel;
p += 3;
pSrc += 3;
}
p += nOffset;
pSrc += nOffset;
}
}
b.UnlockBits(bmData);
bSrc.UnlockBits(bmSrc);
return true;
}
public static bool GaussianBlur(Bitmap b, int nWeight /* default to 4*/)
{
ConvMatrix m = new ConvMatrix();
m.SetAll(1);
m.Pixel = nWeight;
m.TopMid = m.MidLeft = m.MidRight = m.BottomMid = 2;
m.Factor = nWeight + 12;
return BitmapFilter.Conv3x3(b, m);
}
}
class Screenshot
{
public static Bitmap TakeSnapshot(Control ctl)
{
Bitmap bmp = new Bitmap(ctl.Size.Width, ctl.Size.Height);
using (Graphics g = System.Drawing.Graphics.FromImage(bmp))
{
g.CopyFromScreen(
ctl.PointToScreen(ctl.ClientRectangle.Location),
new Point(0, 0), ctl.ClientRectangle.Size
);
}
return bmp;
}
}
I've tried changing every single value in there and it doesn't matter which value(s) I change, I just can't get it to have a stronger blur effect. How can I increase the strength of the Gaussian Blur?
The Form is 80% Opaque, so the blur effect you would see is the windows wallpaper or whatever is behind the form - but blurred. Only problem (as I've said) is that the blur is not strong at all.
After just glancing at the code, it looks to me like the blur filter is hardcoded to only operate in a 3x3 area at a time, severely restricting how blurred it can make an image.
Unless I'm mistaken, the only way to significantly increase the amount of blurring is to find a more sophisticated implementation.