WriteableBitmap generate on thread show on ui - c#

From what i have read and found about the writablebitmap am i not able to change it in a different thread then the one that created it. But i should be able to created it on a diffrent thread then the UI thread, then freze it and parse it to the UI thread for display. Example: Thread cannot access the object
However when i do this, do it tell me "The calling thread cannot access this object because a different thread owns it." who is this, when i have frozen the bitmap?
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Timer imageTimer = new Timer(41);
imageTimer.Elapsed += async (sender, args) =>
{
ImageSource image = await GetImage((int)Math.Ceiling(Image.Width), (int)Math.Ceiling(Image.Height));
DispatcherHelper.CheckBeginInvokeOnUI(() => {
Image.Source = image;
});
};
imageTimer.Start();
}
public Task<WriteableBitmap> GetImage(int width, int height)
{
return Task.Factory.StartNew(() =>
{
WriteableBitmap bitmap = BitmapFactory.New(width, height);
using (bitmap.GetBitmapContext())
{
bitmap.Clear(System.Windows.Media.Colors.AliceBlue);
Random rnd = new Random();
Color[] Colors = new Color[100];
for (int i = 0; i <= 99; i++)
{
Colors[i] = Color.FromRgb((byte)rnd.Next(0, 255), (byte)rnd.Next(0, 255),
(byte)rnd.Next(0, 255));
}
double size = width / 50;
for (int i = 0; i <= 49; i++)
{
int from = (int)Math.Ceiling(size * (double)i);
int to = (int)Math.Ceiling(size * (double)(i + 1)) - 1;
var color = Colors[i];
bitmap.DrawFilledRectangle(from, 0, to, height, color);
}
}
bitmap.Freeze();
return bitmap;
});
}
}
public static class KasperWriteableBitMapExtentions
{
public static void DrawFilledRectangle(this WriteableBitmap bmp, int x1, int y1, int x2, int y2, Color color)
{
// Use refs for faster access (really important!) speeds up a lot!
int w = bmp.PixelWidth;
int h = bmp.PixelHeight;
// Check boundaries
if (x1 < 0) { x1 = 0; }
if (y1 < 0) { y1 = 0; }
if (x2 < 0) { x2 = 0; }
if (y2 < 0) { y2 = 0; }
if (x1 > w) { x1 = w; }
if (y1 > h) { y1 = h; }
if (x2 > w) { x2 = w; }
if (y2 > h) { y2 = h; }
for (int y = y1; y < y2; y++)
{
for (int x = x1; x <= x2; x++)
{
bmp.SetPixel(x, y, color);
}
}
}
}

Related

Draw a Triangle through three points, with known coordinates enclosed within the Triangle

I'am trying to Draw a Triangle in through three points, with known coordinates enclosed within the Triangle.
I wrote this algorithm to do all this, but the code is slow.
Can anyone give me another easy and faster way to draw a Triangle?
I have got the algorithm of drawing the line from this site but do not mention the post sorry.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
public partial class Form1 : Form
{
int Screen_height;
int Screen_width;
List<int> Pointsx = new List<int>(new int[] { });
List<int> Pointsy = new List<int>(new int[] { });
List<int> edge_one_Tranglex= new List<int>(new int[] { });
List<int> edge_one_Trangley = new List<int>(new int[] { });
List<int> edge_two_Tranglex = new List<int>(new int[] { });
List<int> edge_two_Trangley = new List<int>(new int[] { });
List<int> edge_three_Tranglex = new List<int>(new int[] { });
List<int> edge_three_Trangley = new List<int>(new int[] { });
int edge = 1;
Bitmap bmp;
int start = 0;
int center_x;
int center_y;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Screen_height = panel1.Height;
Screen_width = panel1.Width;
Console.WriteLine(" " + Screen_height + "," + Screen_width);
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
if (start == 0)
{
var sw = new Stopwatch();
sw.Start();
bmp = new Bitmap(panel1.Width, panel1.Height);
panel1.BackgroundImage = (Image)bmp;
panel1.BackgroundImageLayout = ImageLayout.None;
//from x to x2 and from y to y2
//D_line(100, 10, -100, 20);
D_Triangle(-300, 10, 100, 20, 100, -100);
sw.Stop();
Console.WriteLine("" + sw.Elapsed);
start += 1;
}
}
public void D_line(int x, int y, int x2, int y2)
{
center_x = Screen_width / 2;
center_y = Screen_height / 2;
line(center_x + x, center_y - y, center_x + x2, center_y - y2);
}
public void line(int x, int y, int x2, int y2)
{
int w = x2 - x;
int h = y2 - y;
int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0;
if (w < 0) dx1 = -1; else if (w > 0) dx1 = 1;
if (h < 0) dy1 = -1; else if (h > 0) dy1 = 1;
if (w < 0) dx2 = -1; else if (w > 0) dx2 = 1;
int longest = Math.Abs(w);
int shortest = Math.Abs(h);
if (!(longest > shortest))
{
longest = Math.Abs(h);
shortest = Math.Abs(w);
if (h < 0) dy2 = -1; else if (h > 0) dy2 = 1;
dx2 = 0;
}
int numerator = longest >> 1;
for (int i = 0; i <= longest; i++)
{
//putpixel(x, y, color);
bmp.SetPixel(x, y, Color.Red);
//my code
if (edge == 1)
{
edge_one_Tranglex.Add(x);
edge_one_Trangley.Add(y);
}
if (edge == 2)
{
edge_two_Tranglex.Add(x);
edge_two_Trangley.Add(y);
}
if (edge == 3)
{
edge_three_Tranglex.Add(x);
edge_three_Trangley.Add(y);
}
if (edge >= 4)
{
if (!Pointsx.Contains(x) || !Pointsy.Contains(y))
{
Pointsx.Add(x);
Pointsy.Add(y);
}
}
numerator += shortest;
if (!(numerator < longest))
{
numerator -= longest;
x += dx1;
y += dy1;
}
else
{
x += dx2;
y += dy2;
}
}
edge++;
// edge_two_Trangle.ForEach(p => Console.WriteLine(p));
}
void D_Triangle(int x1, int y1, int x2, int y2, int x3, int y3)
{
D_line(x1, y1, x2, y2);
D_line(x2, y2, x3, y3);
D_line(x3, y3, x1, y1);
int a = edge_two_Tranglex.Count();
for(int i =1; i < a -1;)
{
line(center_x + x1, center_y - y1, edge_two_Tranglex[i], edge_two_Trangley[i]);
i++;
}
}
}

Hough Line Transform implementation

I am trying to implement Hough Line Transform.
Input. I am using the following image as input. This single line is expected to produce only one intersection of sine waves in the output.
Desired behavior. my source code is expected to produce the following output as it was generated by the sample application of AForge framework.
Here, we can see:
the dimension of the output is identical to the input image.
the intersection of sine waves are seen at almost at the center.
the intersection pattern of waves is very small and simple.
Present behavior. My source code is producing the following output which is different than that of the output generated by AForge.
the intersection is not at the center.
the wave patterns are also different.
Why is my code producing a different output?
.
Source Code
I have written the following code myself. The following is a Minimal, Complete, and Verifiable source code.
public class HoughMap
{
public int[,] houghMap { get; private set; }
public int[,] image { get; set; }
public void Compute()
{
if (image != null)
{
// get source image size
int inWidth = image.GetLength(0);
int inHeight = image.GetLength(1);
int inWidthHalf = inWidth / 2;
int inHeightHalf = inHeight / 2;
int outWidth = (int)Math.Sqrt(inWidth * inWidth + inHeight * inHeight);
int outHeight = 180;
int outHeightHalf = outHeight / 2;
houghMap = new int[outWidth, outHeight];
// scanning through each (x,y) pixel of the image--+
for (int y = 0; y < inHeight; y++) //|
{ //|
for (int x = 0; x < inWidth; x++)//<-----------+
{
if (image[x, y] != 0)//if a pixel is black, skip it.
{
// We are drawing some Sine waves. So, it may
// vary from -90 to +90 degrees.
for (int theta = -outHeightHalf; theta < outHeightHalf; theta++)
{
double rad = theta * Math.PI / 180;
// respective radius value is computed
//int radius = (int)Math.Round(Math.Cos(rad) * (x - inWidthHalf) - Math.Sin(rad) * (y - inHeightHalf));
//int radius = (int)Math.Round(Math.Cos(rad) * (x + inWidthHalf) - Math.Sin(rad) * (y + inHeightHalf));
int radius = (int)Math.Round(Math.Cos(rad) * (x) - Math.Sin(rad) * (outHeight - y));
// if the radious value is between 1 and
if ((radius > 0) && (radius <= outWidth))
{
houghMap[radius, theta + outHeightHalf]++;
}
}
}
}
}
}
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Bitmap bitmap = (Bitmap)pictureBox1.Image as Bitmap;
int[,] intImage = ToInteger(bitmap);
HoughMap houghMap = new HoughMap();
houghMap.image = intImage;
houghMap.Compute();
int[,] normalized = Rescale(houghMap.houghMap);
Bitmap hough = ToBitmap(normalized, bitmap.PixelFormat);
pictureBox2.Image = hough;
}
public static int[,] Rescale(int[,] image)
{
int[,] imageCopy = (int[,])image.Clone();
int Width = imageCopy.GetLength(0);
int Height = imageCopy.GetLength(1);
int minVal = 0;
int maxVal = 0;
for (int j = 0; j < Height; j++)
{
for (int i = 0; i < Width; i++)
{
double conv = imageCopy[i, j];
minVal = (int)Math.Min(minVal, conv);
maxVal = (int)Math.Max(maxVal, conv);
}
}
int minRange = 0;
int maxRange = 255;
int[,] array2d = new int[Width, Height];
for (int j = 0; j < Height; j++)
{
for (int i = 0; i < Width; i++)
{
array2d[i, j] = (maxRange - minRange) * (imageCopy[i,j] - minVal) / (maxVal - minVal) + minRange;
}
}
return array2d;
}
public int[,] ToInteger(Bitmap input)
{
int Width = input.Width;
int Height = input.Height;
int[,] array2d = new int[Width, Height];
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
Color cl = input.GetPixel(x, y);
int gray = (int)Convert.ChangeType(cl.R * 0.3 + cl.G * 0.59 + cl.B * 0.11, typeof(int));
array2d[x, y] = gray;
}
}
return array2d;
}
public Bitmap ToBitmap(int[,] image, PixelFormat pixelFormat)
{
int[,] imageCopy = (int[,])image.Clone();
int Width = imageCopy.GetLength(0);
int Height = imageCopy.GetLength(1);
Bitmap bitmap = new Bitmap(Width, Height, pixelFormat);
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
int iii = imageCopy[x, y];
Color clr = Color.FromArgb(iii, iii, iii);
bitmap.SetPixel(x, y, clr);
}
}
return bitmap;
}
}
I have solved the problem from this link. The source code from this link is the best one I have ever came across.
public class HoughMap
{
public int[,] houghMap { get; private set; }
public int[,] image { get; set; }
public void Compute()
{
if (image != null)
{
// get source image size
int Width = image.GetLength(0);
int Height = image.GetLength(1);
int centerX = Width / 2;
int centerY = Height / 2;
int maxTheta = 180;
int houghHeight = (int)(Math.Sqrt(2) * Math.Max(Width, Height)) / 2;
int doubleHeight = houghHeight * 2;
int houghHeightHalf = houghHeight / 2;
int houghWidthHalf = maxTheta / 2;
houghMap = new int[doubleHeight, maxTheta];
// scanning through each (x,y) pixel of the image--+
for (int y = 0; y < Height; y++) //|
{ //|
for (int x = 0; x < Width; x++)//<-------------+
{
if (image[x, y] != 0)//if a pixel is black, skip it.
{
// We are drawing some Sine waves.
// It may vary from -90 to +90 degrees.
for (int theta = 0; theta < maxTheta; theta++)
{
double rad = theta *Math.PI / 180;
// respective radius value is computed
int rho = (int)(((x - centerX) * Math.Cos(rad)) + ((y - centerY) * Math.Sin(rad)));
// get rid of negative value
rho += houghHeight;
// if the radious value is between
// 1 and twice the houghHeight
if ((rho > 0) && (rho <= doubleHeight))
{
houghMap[rho, theta]++;
}
}
}
}
}
}
}
}
Just look at this C++ code, and this C# code. So, complicated and messy that my brain got arrested. Especially, the C++ one. I never anticipated someone to store 2D values in a 1D array.

Image rotation performance improvement

I am writing code for image rotation. But performance is so bad.
When I use 10000 x 10000 image, it took about 100 minutes. I want to speed up up to < 1~3 min, but I don't know how I can improve this code.
This code is for huge size images (over 4gb), and process single line of image sequentially.
I attach full code. First I do x-y movement transformation, after that I perform angle transformation.
Here is code for this. Environment is .net framework 4.6.2, 64bit.
Test code: I used "emgucv3 and speedycoding" library from nuget package
flatten method is from speedycoding , and Image<Gray, byte> from emgucv3
Image<Gray,byte> img = new Image<Gray, byte>(imgpath);
PointD[] posdList = new PointD[4]
{
new PointD(-1024,48),
new PointD(-3264,0),
new PointD(639,-2016),
new PointD(3119,1696)
};
var data = img.Data.TointArray();
var dataW = img.Data.GetLength(1);
var dataH = img.Data.GetLength(0);
var strideW = dataW % 4;
var strideH = dataH % 4;
posdList = posdList.Select( x => new PointD( x.X * ratio + dataW/2, x.Y * ratio+dataH/2 ) ).ToArray();
img = img.Resize( dataW + ( strideW == 0 ? 0 : 4 - strideW ), dataH + ( strideH == 0 ? 0 : 4 - strideH ), Inter.Cubic );
data = img.Data.TointArray();
dataW = img.Data.GetLength(1);
dataH = img.Data.GetLength(0);
var srcdata = img.Data.Flatten();
byte[][] temprers;
using (MemoryStream mstream = new MemoryStream(srcdata))
{
temprers = Run(mstream, dataW, dataH, posdList);
}
This is main run code.
public static byte[][] Run(MemoryStream bytestream, int w, int h, PointD[] pos3)
{
try
{
Stopwatch stw = new Stopwatch();
var srcPos = new AffinePos(pos3[0], pos3[1], pos3[2], pos3[3]);
var trsData = srcPos.ToTrnsData(w, h);
var xc = trsData.XSrcCnter;
var yc = trsData.YSrcCnter;
var xmax = Math.Max(w - xc, xc) * 2;
var ymax = Math.Max(h - yc, yc) * 2;
byte[][] R1 = CreateJagged(ymax, xmax);
for (int i = 0; i < h; i++)
{
var data = new byte[w];
bytestream.Seek(i * w, SeekOrigin.Begin);
bytestream.Read(data, 0, w);
var reshaped = data.Reshape(1, w).ToJagged();
xytransform(ref R1, trsData, reshaped, i, xmax, ymax);
}
var w1 = R1[0].Length;
var h1 = R1.Length;
var degree = trsData.Angle * 180 / Math.PI;
double radian = trsData.Angle;
double cosRadian = Cos(radian);
double sinRadian = Sin(radian);
int newWidth = (int)(w1 * Abs(cosRadian) + h1 * Abs(sinRadian));
int newHeight = (int)(h1 * Abs(cosRadian) + w1 * Abs(sinRadian));
Console.WriteLine( "Create Jagged (sec)" );
stw.Start();
byte[][] R2 = CreateJagged(newWidth, newHeight);
stw.Stop();
Console.WriteLine( stw.ElapsedMilliseconds / 1000 );
Console.WriteLine( "Length : {0} / (ms)", R1.Length );
for (int i = 0; i < R1.Length; i++)
{
var reshaped = R1[i].Reshape(1, w1).ToJagged();
Stopwatch stwinnter = new Stopwatch();
stwinnter.Start();
rotateGeneral(ref R2, trsData, reshaped, i, w1, h1);
stwinnter.Stop();
Console.WriteLine( stwinnter.ElapsedMilliseconds );
}
return R2;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
return null;
}
}
public static void xytransform(ref byte[][] target, TrnsData data, byte[][] src, int hidx, int xmax, int ymax)
{
var h = src.GetLength(0);
var w = src[0].GetLength(0);
var tcenterX = (int)xmax / 2;
var tcenterY = (int)ymax / 2;
var xshift = (int)(data.XSrcCnter - tcenterX);
var yshift = (int)(data.YSrcCnter - tcenterY);
for (int j = 0; j < h; j++)
{
for (int i = 0; i < w; i++)
{
if (i - xshift >= 0
&& j - yshift >= 0
&& i - xshift < target[0].Length
&& j - yshift < target.Length)
{
var yidx = (j - yshift + hidx).ToString();
var xidx = (i - xshift).ToString();
if (j - yshift + hidx * h < target.Length
&& i - xshift < target[0].Length)
{ target[j - yshift + hidx * h][i - xshift] = src[j][i]; }
}
}
}
}
public static void rotateGeneral(ref byte[][] target, TrnsData data, byte[][] G, int hidx, int oldw, int oldh)
{
double radian = data.Angle;
var newWidth = target[0].Length;
var newHeight = target.Length;
double cosRadian = Cos(radian);
double sinRadian = Sin(radian);
int centerX = oldw / 2;
int centerY = oldh / 2;
int diffX = (newWidth - oldw) / 2;
int diffY = (newHeight - oldh) / 2;
double sourceX, sourceY;
int isourceX, isourceY;
int isourceX2, isourceY2;
int h = G.Length;
var temptarget = target;
Parallel.For( 0, target.Length ,
y =>
{
for (int x = 0; x < temptarget[0].Length; x++)
{
var dx = x - (centerX + diffX);
var dy = y - (centerY + diffY);
var xres = dx * cosRadian - dy * sinRadian;
var yres = dx * sinRadian + dy * cosRadian;
var srcX = xres + centerX;
var srcY = yres - hidx * h + centerY;
var isourceX_ = (int)Math.Round( srcX );
var isourceY_ = (int)Math.Round( srcY );
//try
//{
if (isourceY_ < G.Length
&& isourceY_ >= 0
&& isourceX_ < G[0].Length
&& isourceX_ >= 0)
{
temptarget[y][x] = G[isourceY_][isourceX_];
}
//}
//catch (Exception es)
//{
// Console.WriteLine( es.ToString() );
//}
}
} );
target = temptarget;
}
transData class is this
public struct TrnsData
{
public double Innerw;
public double Innterh;
public int H;
public int W;
public int XSrcCnter;
public int YSrcCnter;
public int XShift;
public int YShift;
public int dX;
public int dY;
public double Angle; // radian
}
public class AffinePos
{
public PointD LB;
public PointD LT;
public PointD RT;
public PointD RB;
public AffinePos(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
{
LB = new PointD(x1, y1);
LT = new PointD(x2, y2);
RT = new PointD(x3, y3);
RB = new PointD(x4, y4);
}
public AffinePos(PointD lb, PointD lt, PointD rt, PointD rb)
{
LB = lb;
LT = lt;
RT = rt;
RB = rb;
}
}
This is extension method for create TrnsData
public static TrnsData ToTrnsData
(this AffinePos srcPos, int w, int h)
{
var innerh = PosL2(srcPos.LB, srcPos.LT);
var innerw = PosL2(srcPos.RT, srcPos.LT);
var trgPos = srcPos.MoveToCenter(new PointD(w / 2.0, h / 2.0)); // ok
var fcenterX = srcPos.GetCenter().X;
var fcenterY = srcPos.GetCenter().Y;
var lcenterX = trgPos.GetCenter().X;
var lcenterY = trgPos.GetCenter().Y;
var xshift = lcenterX - fcenterX;
var yshift = lcenterY - fcenterY;
var dx = srcPos.LT.X - srcPos.RT.X;
var dy = srcPos.LT.Y - srcPos.RT.Y;
double radian;
if (Abs( dx) < 0.0001)
{
radian = 1.5708;
}
else if (Abs(dy) < 0.0001)
{
radian = 3.14159;
}
else
{
radian = Math.Atan(dy / dx);
}
return new TrnsData()
{
H = h,
W = w,
XShift = (int)xshift,
YShift = (int)yshift,
Innerw = innerw,
Innterh = innerh,
XSrcCnter = (int)fcenterX,
YSrcCnter = (int)fcenterY,
dX = (int)dx,
dY = (int)dy,
Angle = radian,
};
}
and additional extension method
public static byte[][] CreateJagged(int h, int w)
{
byte[][] output = new byte[h][];
for (int i = 0; i < h; i++)
{
output[i] = new byte[w];
}
return output;
}

C# Bitmap class as field?

I'm trying to make this class for processing images, and I wanted it to have a Bitmap field, and a constructor that would allow me to give to path to the bitmap so other methods could use that bitmap. So I wanted it to be able to do this:
ImageProcessing image = new ImageProcessing("D:\\image.bmp");
int time_of_processing = image.grayscale();
image.SaveTo("D:\\image2.bmp");
And so this is my code:
public class ImageProcessing
{
Bitmap image;
public ImageProcessing(string path)
{
image = new Bitmap(path);
}
public int Grayscale()
{
Stopwatch time = new Stopwatch();
time.Start();
for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
Color pixelColor = image.GetPixel(x, y);
int grayScale = (int)((pixelColor.R * 0.21) + (pixelColor.G * 0.72) + (pixelColor.B * 0.07));
Color newColor = Color.FromArgb(grayScale, grayScale, grayScale);
image.SetPixel(x, y, newColor);
}
}
time.Stop();
TimeSpan ts = time.Elapsed;
int milliseconds = ts.Milliseconds + (ts.Seconds * 1000);
return milliseconds;
}
public void SaveTo(string path)
{
image.Save(path);
}
}
And when i have this, Visual Studio tells me that image will always be null. How should the constructor look for it to work?
Add the namespace to the ImageProcessing class when you use it to make sure its always using the correct class. The following code (which is mostly just the original code) has been tested and works (it grayscales the image listed).
namespace WindowsFormsApplication10
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
string path1 = #"C:\work\test.bmp";
string path2 = #"C:\work\test2.bmp";
WindowsFormsApplication10.ImageProcessing image = new WindowsFormsApplication10.ImageProcessing(path1);
int time_of_processing = image.Grayscale();
image.SaveTo(path2);
}
}
public class ImageProcessing
{
Bitmap image;
public ImageProcessing(string path)
{
image = new Bitmap(path);
}
public int Grayscale()
{
Stopwatch time = new Stopwatch();
time.Start();
for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
Color pixelColor = image.GetPixel(x, y);
int grayScale = (int)((pixelColor.R * 0.21) + (pixelColor.G * 0.72) + (pixelColor.B * 0.07));
Color newColor = Color.FromArgb(grayScale, grayScale, grayScale);
image.SetPixel(x, y, newColor);
}
}
time.Stop();
TimeSpan ts = time.Elapsed;
int milliseconds = ts.Milliseconds + (ts.Seconds * 1000);
return milliseconds;
}
public void SaveTo(string path)
{
image.Save(path);
}
}
}

how do i use background Worker in this for loop c#

How do I use a background worker in this for loop?
int tmax = 10;
int xmax = newbitmap.Width;
int ymax = newbitmap.Height;
for (int t = 0; t <= tmax; t += 1)
{
for (int x = 0; x < xmax; x++)
{
for (int y = 0; y < ymax; y++)
{
if ((x / xmax) > (t / tmax))
{
Color originalco = newbitmap2.GetPixel(x, y);
outp.SetPixel(x, y, originalco);
}
else
{
Color originalco3 = newbitmap.GetPixel(x, y); ;
outp.SetPixel(x, y, originalco3);
}
}
pictureBox1.Image = outp;
}
}
This loop is a wipe transition from right to left, but it doesn't display the transition.
That because the backgroundWorker works in a different thread. You can use backgroundworker.ReportProgress(0, outp)
So:
You need to register to the event BackgroundWorker.ProgressChanged from the events window in Vistual Studio, or with this line:
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
The method:
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
var outp = (Bitmap)e.UserState;
prictureBox.Image = outp;
}
Your code sould be then:
int tmax = 10;
int xmax = newbitmap.Width;
int ymax = newbitmap.Height;
for (int t = 0; t <= tmax; t += 1)
{
for (int x = 0; x < xmax; x++)
{
for (int y = 0; y < ymax; y++)
{
if ((x / xmax) > (t / tmax))
{
Color originalco = newbitmap2.GetPixel(x, y);
outp.SetPixel(x, y, originalco);
}
else
{
Color originalco3 = newbitmap.GetPixel(x, y); ;
outp.SetPixel(x, y, originalco3);
}
}
backgroundWorker1.ReportProgress(t, outp);
}
}
First, you should use direct pixel manipulation as described here: http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx
Then, you should use an array as lookup for all your threads which line has already been drawn and which hasn't. The threads look for a new line in this array and then draw it. But remember to lock the lookup array!
Your Do work method would look something like this: -
private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
Bitmap newbitmap = (Bitmap)e.Argument;
int tmax = 10;
int xmax = newbitmap.Width;
int ymax = newbitmap.Height;
for (int t = 0; t <= tmax; t += 1)
{
for (int x = 0; x < xmax; x++)
{
for (int y = 0; y < ymax; y++)
{
if ((x / xmax) > (t / tmax))
{
Color originalco = newbitmap2.GetPixel(x, y);
outp.SetPixel(x, y, originalco);
}
else
{
Color originalco3 = newbitmap.GetPixel(x, y); ;
outp.SetPixel(x, y, originalco3);
}
}
pictureBox1.Image = outp;
}
}
bgWorker.ReportProgress(0,outp);
}
Then when your worker reports progress, it would raise the following event where you can safely update the UI:
private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//UPDATE YOUR UI HERE
}
You can use the ReportProgress method of Background Worker to update the UI.
Read more

Categories

Resources