Click here to Skip to main content
15,885,546 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hello there,
I've a little problem.

Imagine the code here:
C#
public partial class Window1 : Window
{
	fastbitmap fastbm;//own made class
	WriteableBitmap bitmapBuffer;//WriteableBitmap
	volatile bool IsWorking = false;
	
	public Window1()
	{
		//load a new image
		fastbm = new fastbitmap("Some Image.jpg");
		//throw a working copy in the writeablebitmap
		bitmapBuffer = fastbm.toWriteableBitmap();
		
		Photo p = new Photo();//photo control contains an Image
		//Sets the Image.Source
		//right now the Source is bound with the writeablebitmap
		//this will cause the Image to update automatically after an update
		//of the writeablebitmap's back buffer
		System.Windows.Controls.Image i = p.SetPicture(ref writeablebm);
		//use high quality scaling
		RenderOptions.SetBitmapScalingMode(i, BitmapScalingMode.HighQuality);
		
		//finally: put the photo in a grid
		p.HorizontalAlignment = HorizontalAlignment.Center;
		p.VerticalAlignment = VerticalAlignment.Center;
		this.myGrid.Children.Add(p);
		
		
		//Also an event, which will be thrown up from a different thread
		Some.Event += new Some.Event(Someevent);
	}
	
	//the event will init a new update of the writeablebitmap
	void Someevent(object sender, Eventargs args)
	{
		//this event will be called ~30 times per second
		//make sure this isn't running already
		if(!IsWorking)
		{
			MyDelegate instance = new MyDelegate(UpdateBitmap);
			this.Dispatcher.Invoke(instance, null);
		}
	}
	
	delegate void MyDelegate();
	void UpdateBitmap()
	{
		IsWorking = true;
		//do some effects to the image etc.
		fastbm.dosomething();
		//write the new updated image to the backbuffer.
		//this is done via unsafe code, and the bitmapBuffer's 
		//back buffer will be locked at that time.
		fastbm.toWriteableBitmap(ref bitmapBuffer);
		//let other work happen again
		IsWorking = false;
	}
}


this is just a simplified version of what I'm doing, but this code works.
Unfortunately it's not visible!

The backbuffer of the writeablebitmap is being filled so quickly everytime by the event that the image doesn't have the chance to update.
Probably somewhere in the middle of transferring the backbuffer to the frontbuffer (so it can be displayed) the backbuffer is being changed again.

Also when I create a new WriteableBitmap every time and load it up the Image simply doesn't load fast enough to show.

I'd like to bind the resources together tho, since that's more efficient. So I need to know a way to detect when the Image is finished loading and the "IsWorking" value can be set to false again.
So far I haven't found any variable or event that does this properly.

Does anyone of you know a way to detect when an Image is finished loading and rendering, so I can pause the update till that time.
I would seriously appreciate any help.

Thanks in advance!

edit: fastbitmap functions to write to writeablebitmap (on request)
they use unsafe code since the other way of doing it didn't work out properly... some weird .net documentation imho
C#
public WriteableBitmap toWriteableBitmap()
{
	WriteableBitmap bm = new WriteableBitmap(this.Width, this.Height, 300, 300, PixelFormats.Bgr24, null);
	unsafe
	{
		bm.Lock();
		int currentPixel = -1;
		byte* pStart = (byte*)(void*)bm.BackBuffer;
		
		Colour c;
		for (int y = 0; y < Height; y++)
		{
			for (int x = 0; x < Width; x++)
			{
				currentPixel++;
				c = bmdata[x][y];
                                //Note: B,G and R are bytes
				*(pStart + currentPixel * 3) = c.B;
				*(pStart + currentPixel * 3 + 1) = c.G;
				*(pStart + currentPixel * 3 + 2) = c.R;
			}
		}

		bm.AddDirtyRect(new Int32Rect(0, 0, Width, Height));
		bm.Unlock();
	}
	return bm;
}

public void toWriteableBitmap(ref WriteableBitmap bm)
{
	if (bm == null)
	{
		bm = toWriteableBitmap();
		return;
	}
	if (bm.Format != PixelFormats.Bgr24)
		throw new Exception("Pixelformat should be Bgr24!");
	if (bm.PixelWidth!= this.Width || bm.PixelHeight != this.Height)
		throw new Exception("WriteableBitmap doesn't have the same size as fastbitmap");

	unsafe
	{
		bm.Lock();
		int currentPixel = -1;
		byte* pStart = (byte*)(void*)bm.BackBuffer;

		Colour c;
		for (int y = 0; y < Height; y++)
		{
			for (int x = 0; x < Width; x++)
			{
				currentPixel++;
				c = bmdata[x][y];
				*(pStart + currentPixel * 3) = c.B;
				*(pStart + currentPixel * 3 + 1) = c.G;
				*(pStart + currentPixel * 3 + 2) = c.R;
			}
		}

		bm.AddDirtyRect(new Int32Rect(0, 0, Width, Height));
		bm.Unlock();
	}
}
Posted
Updated 5-Jan-12 11:36am
v3
Comments
Sergey Alexandrovich Kryukov 5-Jan-12 17:27pm    
How can we find out what's wrong without having the code of fastbitmap?
Also, you did not explain the goal of all that. Waiting for the update looks like a big misconception at first glance. Is is some kind of animation or what?
--SA
wpte 5-Jan-12 17:33pm    
code added... it works if I do it every second, but I want to have it continuously.
Don't ask me why I want that, I just do :)

The image is being edited with several filters with some OpenCL code. It's not an animation, it has to respond very quickly tho.
Sergey Alexandrovich Kryukov 13-Mar-13 17:18pm    
Please stop posting non-answers as "solution". It can give you abuse reports which eventually may lead to cancellation of your CodeProject membership. And the fact you even self-accepted on formally is just outrageous, a sure way for a ban. I hope you won't do it after this warning.

Comment on any posts, reply to available comments, or use "Improve question" (above).
Also, keep in mind that members only get notifications on the post sent in reply to there posts.
—SA
wpte 13-Mar-13 17:54pm    
I find outrageous a big word to be quite honest. If the OP found a solution to his/hers problem it shouldn't be that weird to accept that as a solution when nothing else comes up.
I do agree with that my "solution" isn't really that much of a solution. The solution more or less is, that it's impossible. Point is that it worked for me and thus is a solution for me and thus I (apparently mistakenly) posted it as a solution.

Nevertheless, I apologize, next time I'll put it in a comment or improve my answer, whichever the most appropriate.
Sergey Alexandrovich Kryukov 13-Mar-13 18:35pm    
You do have your point, but please also understand: we are overwhelmed with non-questiona, and also with some massive faked answers from some dishonest members. Even if your post makes sense (in some cases, such posts do make sense), so it's hard to segregate "good guys" from "bad guys", so I think some formal approach can help to sanitize the situation.

Please understand that I really appreciate your collaborative attitude.

And I absolutely don't want to limit your ability to adequately respond to the situation when you don't have helpful response from experts and then you suddenly realize that you have a better solution. You have the following respectable options: 1) you can use "Improve question" and add the description of the solution; if it was not yours, you are supposed to credit the source of it; 2) if this is your solution and you think it is really valuable, you can write a short Tips & Tricks article and include the reference to your original question if you want that. The second option is a really good idea and such short articles are highly visible.

In some cases, when you see the solution to your question, which is trivial, you can choose to remove your original question, but we ask not to do it if you have real answers from others.

In all other cases, you can use comments.

You don't need to apologize, the situation is natural, and you did not actually try to do anything intentionally bad. I'm just trying to improve things, as there is a number of members who intentionally fake and plagiarize posts using some leaks in site functionality. We report bad cases in a special abuse watch forum, and members vote for banning which happens automatically. Of course, I did not report you; that's why I've chosen to talk to your personally. I hope you understand.

Again, thank you for your understanding and your collaboration.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900