Auto scrolling or shifting a bitmap in .NET - c#

I have a .NET GDI+ bitmap object (or if it makes the problem easier a WPF bitmap object) and what I want to to is shift the whole lot by dx,dy (whole pixels) and I would ideally like to do it using .NET but API calls are ok.
It has to be efficient bacause its going to be called 10,000 times say with moderately large bitmaps.
I have implemented a solution using DrawImage - but its slow and it halts the application for minutes while the GC cleans up the temp objects that have been used.
I have also started to work on a version using ScrollDC but so far have had no luck getting it to work on the DC of the bitmap (I can make it work buy creating an API bitmap with bitmap handle, then creating a compatible DC asnd calling ScrollDC but then I have to put it back into the bitmap object).
There has to be an "inplace" way of shifting a bitmap.
mikej

Have you found the Graphics.FromImage method? That will let you manipulate the bitmap directly. I'm not sure what you're using with DrawImage, but Graphics.DrawImage should let you copy an area of the bitmap onto itself (and apply a shift in the process).
Alternatively, given a Graphics object, you can use Graphics.GetHdc, ScrollDC and Graphics.ReleaseHdc.

Do you just want to move the whole graphic? DrawImage has x,y parameters to do that. I'm probably not interpreting your question correctly.
As an aside, GDI is not going to be efficient period when you're working with 10,000 images. If you want anywhere near real-time performance you're going to have to either rework your algorithm or look into a 3D API (like DirectX or OpenGL) or possibly both.

Sorry if my question wasn't too clear.
All I'm trying to do is in place scroll a bitmap i.e. do a shift operation.
For example, a method like Scroll(B,1,0) would shift the entire bitmap B one pixel to the right.
I've got reasonable solution using both DrawImage and the ScrollWindowEx API call which is about 10 time faster.
I'm still trying to work out how I could do something faster using WPF.

I've written up my solution to the problem at Scrolling a bitmap but I'm still not sure that there isn't a better way and if it might be better done in say WPF?

Related

Draw on PNG without System.Drawing.Graphics

For debugging purposes, I'd like to draw on an image in my c# app (I have lots of tiles and I'd like to know which one is which). However, when trying to do it via System.Drawing.Graphics, I run into the fact that the image I'm trying to draw on is a GIF (which I don't have any choice over). Is there another way to draw on images in c#/.NET without using the classes in System.Drawing?
Technically, this isn't the question you asked, but I'm guessing the reason you're not able to draw on the Bitmap from your GIF is that the pixel format is indexed. If so, that's easy to work around by making a copy with a non-indexed format using the Bitmap.Clone method. Just give it the full bitmap size and PixelFormat.Format32bppArgb.
I don't know any other standard drawing API's in .NET that are convenient for this purpose.

C# fast pixel rendering

I'm developing depth processing (Xbox Kinect, Asus Xtion, etc) applications using OpenNI.
I need a really simple and fast way of drawing on a Windows form when new depth data is available from the sensor (30 or 60 fps depending on resolution).
Currently I'm invalidating a double-buffered panel from a seperate thread when the data becomes available, and then setting pixels of a bitmap in the panel's paint method, yielding a predictably awful 5fps.
System.Drawing.Graphics seems to lack a fast way to set individual pixels, unless anyone can instruct otherwise.
I literally just need to set pixel colours, so would like to avoid using third party high speed rendering APIs if possible, and ideally use something as native as possible.
Does anyone have any suggestions?
If you're using Bitmaps, then you should use LockBits and UnlockBits to access the data directly in memory. In C#, you can get some extra performance by using unsafe code blocks and pointers.
See this link for more information: http://web.archive.org/web/20150227183132/http://bobpowell.net/lockingbits.aspx
image.SetPixel() is very slow when you are replacing many pixels per frame and you need many frames per second.
It will be a lot faster when you use a WriteableBitmap and call CopyPixels
This way you can fill the array with pixel data using multiple threads and simply blit the array to the image in a single call.
EDIT
Note that WriteableBitmap is a WPF class. If you are bound to WinForms you might need to create your own implementation. WPF/WinForms/GDI interop: converting a WriteableBitmap to a System.Drawing.Image?
You could try my LINQ image processing library to work with your "buffer-bitmaps". It uses an accessible LINQ syntax but is very performant for large bitmaps. It is available on Nuget as a single file include in your project.
Hope that helps!

C# Double Buffering?

I am using the COSMOS compiler to write an OS in C# (For those who dont know COSMOS converts IL code into x86 assembly) and I am making a GUI.
I have made GUIs before but now i am trying to make a double buffer.
It sounds rather easy but following is my problem -
I cant use any methods from the System.Drawing Library or any other namespace that uses p/ invokes. Also, I can not use multi Dimensional arrays (I CAN use regular arrays). So my question is how would I implement double buffer?
I know it is possible because I know someone who did it.
Additionally, the only graphical functions I have are SetPixel , GetPixel and Clear. All though I prefer an answer , if any one knows a good article about double buffering ect please tell me.
PS. My OS in 320 x 200 Res LOL
You will need to learn a little bit of DOS C VGA game lore it sounds like ;-)
See Double Buffering, Page Flipping, & Unchained Mode. All the same concepts apply, not sure how they will translate to the C# code though.
Happy coding.
Try to see if you can access System.Drawing.BufferedGraphics. It implements methods for that purpose. Otherwise, I'm afraid you have to do it manually.
Usually, when you draw directly on the screen, the user sees what you’re drawing as it’s being drawn. It’s like when you ask Alex to draw you an apple; you’ll examine him while he draws the apple with the pen. Now if you ask Alex to draw a red apple, then erase it, then draw a blue apple, then erase it then draw a yellow apple, etc… You’ll be looking at him while he’s erasing it each time. Think of it this way: The computer is a fast Alex. So if you ask for a fast animation to be drawn directly on the screen, the user will mark that something is happening between the animation frames: bad flickering!
The solution to flickering is double buffering. A buffer is simply an off-screen area of memory used for drawing. When you use double buffering, instead of drawing directly to the screen, you draw to a back buffer, located in the video memory, and then copy the entire buffer to the screen.
Double buffering can be implemented by using an array to plot to (as opposed to the display) and by blitting the array (when finished plotting) to the display.

Best way to constantly draw large numbers of bitmaps in WPF?

I am stumped by this very simple problem. I am making a tile-based game engine and need to be able to allow a user to edit the map using a WPF User Interface. Naively, I had assumed that I could simply constantly update a good old fashioned "buffered" System.Drawing.Graphics.Bitmap using Graphics.FromImage. I would draw onto the bitmap the tiles that make up the map, and then blit the buffer Bitmap to the screen. However, from my thorough research I now believe that it isn't that easy at all.
Rather than bore you with what I've found out so far (that either doesn't work, or is incredibly slow), may I ask very simply, what is the best way for continuously drawing large numbers of bitmaps efficiently via a WPF UI?
I will accept such suggestions as "go back to Windows Forms". If that's the case, then I am going to be very dissapointed with WPF!
The WriteableBitmap class is a high-performance WPF-compatible bitmap that allows direct access to its bits. This MSDN documentation page contains a fairly thorough example of using it.
Freezable can make a big difference to performance when dealing with Bitmaps, you can then also load the buffer using a background thread to stop the UI locking up.
This tutorial covers the basics

Large bitmap maniuplation in WPF

Is WPF be able to manipulate large bitmaps where GDI+ cannot due to memory limitations?
I have bitmaps that are 10,000x10,000 easily, and could even be much larger than that. Worst case I think I can break the single bitmap into large tiles and work with that I guess.
I basically need to do four things
Take an set of tiled images
Put all of those tiles into a single bitmap
Convert the bitmap to black and white
Scan the bitmap looking for changes from black to white
I know how to do these things in GDI+, but the problem I am running into is that the size of my bitmap is too large for the machine I am using, and it causes the program to crash, and I cannot make the image any smaller, so I am hoping that WPF will be able to succeed where GDI+ has failed me.
I don't think WPF will be able to help you here.
Why do you want to use bitmap object? You may as well work with an two-dimensional array of bytes or doubles (or any other type, depending oh what accuracy and range do you need), especially if you work with one channel only. Bitmaps have accessor methods (GetPixel and such) with huge computational overhead, working with arrays is by orders of magnitude faster (I know from personal experience), the only issue is that you can't display them as they are (you would have to convert the array back into image, which is fairly simple). But since you seem to want to do some sort of analysis on the data, I think array would be much more suitable for your needs.
I can post code samples detailing conversion from bitmap (either WPF or WinForms) to array an back if you want.
But remember, that 32bit .NET application can use approximately 1.2-1.4 gigabytes of memory - you have to fit in this space or you start getting OutOfMemory exceptions.
I eventually decided that the best course of action was to only work with the tiles, and then have an array that holds the actual information about each tile that I need. Given the number of tiles, it was the only sensible thing I could do.
Like CommanderZ said. Its Windows PRESENTATION Foundation, not Windows Image-manipulation Foundation.
You should try to either find some kind of image-manipulation library, but looking at size of your image, then doing everything yourself might be only way.
Especialy, you probably wont be able to work with bitmap as a whole, so you are going to work with tiles. Then it becomes problematic if you need to work with neighboring pixels. But I guess you should look into this yourself.

Categories

Resources