473,394 Members | 2,048 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Bitmap <-> ArrayList of points

Hello!
My goal is to develop a program that opens a bitmap, copies its pixels
to an ArrayList in order to perform some complex calculations (edge
detection, Hough transform etc.), and save resulting image back in some
other bitmap.

It works pretty fast, except for stages of coping pixels between bitmap
(object of type Bitmap) and the ArrayList. I'm using the trivial
solution with two loops:

for (int y=0; y<bmp.Height; y++)
for (x=0; x<bmp.Width; x++)

which seems to be very time-consuming -- for any image I tried, copying
each pixel from Bitmap to the ArrayList (and vice-versa) takes more
time than performing edge detection on pixels stored in the ArrayList!

Is there any way to make that process faster?

--
Regards,

Iwanow

Jul 30 '06 #1
3 3093
Iwanow wrote:
It works pretty fast, except for stages of coping pixels between bitmap
(object of type Bitmap) and the ArrayList. I'm using the trivial
solution with two loops:

for (int y=0; y<bmp.Height; y++)
for (x=0; x<bmp.Width; x++)
And what's inside those loops? How do you access the pixels?

Try to use a DIB instead of a bitmap. The terminology seems to be a bit
confusing, but a DIB (created using CreateDIBSection) resides in the
physical memory, and is as fast as memory allocated with malloc. On the
other hand, a bitmap (created using CreateBitmap) doesn't have a pointer
in the RAM. I believe it resides in the video memory, and yes, it takes
enormous emount of time to transfer data between the RAM and the VRAM
(in most cases much more time than to process the image itself).

I personally don't care about bitmaps unless I really need to display
them on the screen. Even then, instead of using bitmaps, I prefer the
DrawDibDraw API, which allows me to use my own data structures. I almost
never use Windows bitmap functions. Windows can't load and save my image
files anyway.

In .NET, I achieved better results with cli::array<than with List<>,
and ArrayList is a huge no no. ArrayList stores Object^ handles, not
numeric values, which means each of your pixel will silently allocate an
managed object of its own. Don't ever use ArrayList, it's evil! That
would explain why it's so slow for you. If it's an RGB image, than each
pixel will allocate 3 managed objects. That means 200 million .NET
objects will be allocated with an 11x17" 600 DPI color drawing!

I strongly recommend that you start using cli::array. In image
processing, you always know the size of the image in advance, and it
doesn't grow. But even if you must use a dynamic array, please stay away
from ArrayList at all times.

Tom
Jul 31 '06 #2
Tamas Demjen wrote:
I strongly recommend that you start using cli::array. In image
processing, you always know the size of the image in advance, and it
doesn't grow. But even if you must use a dynamic array, please stay away
from ArrayList at all times.
Thank you for that hint. Up to now, I've been using... ArrayLists to
store my data. Therefore, I'll need to change it to the cli::array.

I use Bitmap objects as sources of original images, and a destinations
after processing. I usually access them through either:
- bmp->GetPixel(x, y).GetBrightnes() or
- bmp->SetBixel(x, y, Color)
Both functions are called within 'for' loops mentioned in my first
post. Will they work faster with cli::array?

--
Iwanow

Aug 2 '06 #3
Iwanow wrote:
Thank you for that hint. Up to now, I've been using... ArrayLists to
store my data.
ArrayList stores System::Object^ managed handles. If you add an integer
value to an ArrayList, it wraps that value into a managed object. This
is called boxing. The C++/CLI compiler automatically generates code that
wraps your integer value into a garbage collected object. In the old
MC++, you had to explicitly __box() them. Either way, this is a major
performance penalty, and a waste of memory too. That's why I suggested
using array<unsigned char>, or even List<unsigned char(if you're
programming in .NET 2.0). List has an overhead to array, but if used
correctly, it's almost negligible. It's like the difference between
char* and std::string.
I use Bitmap objects as sources of original images, and a destinations
after processing. I usually access them through either:
- bmp->GetPixel(x, y).GetBrightnes() or
- bmp->SetBixel(x, y, Color)
Both functions are called within 'for' loops mentioned in my first
post. Will they work faster with cli::array?
I'm pretty sure that grabbing a pointer to the raw image data would be
many times faster than GetPixel. I don't know how GetPixel works, but it
must do at least a multiplication and an addition (usually TopLeftPtr +
x - y * BytesPerLine, assuming the image is upside down). This is many
times slower than incrementing a pointer.

Even if you use array<unsigned char>, using the array syntax happens to
be much slower for me than interior_ptr<unsigned char>. What I do is the
following:

array<unsigned charbuffer = gcnew array<unsigned char>(width * height);
interior_ptr<unsigned shortptr = &buffer[0];
while(/*...*/)
{
*ptr++ = /*...*/;
}

This trick alone made my code about twice as fast than using array
syntax, like buffer[offset++].

I'm not familiar with the Bitmap class, but I know it has a way to lock
its pixels and get a byte pointer to its raw underlying data. Here's an
example:

http://vbforums.com/showthread.php?t=260903

I think the C# byte* is the same as the C++/CLI interior_ptr<unsigned char>.

I recommend that you research Bitmap::LockBits and BitmapData a bit:
http://msdn2.microsoft.com/en-us/lib...itmapdata.aspx

Note that if you do this, you must deal with the following:
- windows bitmaps are upside down
- the raw data depends on the bits per pixel value. There are 1, 4, 8,
16, 24, 32-bit images. You must decode the color data from the raw bits
on your own (which is very easy with 8 and 24-bit images, a bit tricky
with 16-bit images, but I refuse to work directly with 16-bit bitmap)
- each line begins on a DWORD boundary, so usually there are some
padding bytes after the last pixel in each line. Here's how to calculate
the number of bytes per line:
BytesPerLine = (Width * BitsPerPixel + 31) / 32 * 4 * Height;

Since images are upside down, the last line is in fact the first, and
instead of incrementing the line pointer by BytesPerLine, you have to
decrement it.

Note that I have very little .NET experience compared to unmanaged code.
99.99% of my code is native C++. You should really do your own
benchmarking with your own algorithm, but you should get much better
result with Bitmap::LockBits than with GetPixel.

Tom
Aug 2 '06 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: charsh | last post by:
Hi, I using the code below to draw a text in a pictureBox1. //Start--------------------------------------------------------------- private void button1_Click(object sender, System.EventArgs e)...
2
by: Sharon | last post by:
I encountered a strange behavior when doing ‘new Bitmap’: The following code works fine and the given bitmap file is shown on the PictureBox (the m_DrawArea) in the correct bitmap sizes: ...
5
by: Lance | last post by:
I need to create a Drawing.Bitmap from an array of integer values. My current technique creates a bitmap that eventually becomes corrupt (i.e., the bitmap's pixels change to a different color...
8
by: Nathan Sokalski | last post by:
I am trying to write code to rotate a graphic that I have. Here is the code I am currently using: Dim frogbitmap As New Bitmap(Drawing.Image.FromFile(Server.MapPath("images/frog.gif"))) Dim...
7
by: Fir5tSight | last post by:
Hi All, I used the following code in C#: using System.Drawing; //blah blah blah Bitmap bmp = new Bitmap();
14
by: eliss.carmine | last post by:
I'm using TCP/IP to send a Bitmap object over Sockets. This is my first time using C# at all so I don't know if this is the "right" way to do it. I've already found out several times the way I was...
0
by: benfly08 | last post by:
Hi, guys. I have a program to draw bar/pie chart based on the data i hard coded in it. However, my image comes with "BLACK" background color. I don't know how to fix this. The code snippet is...
8
by: Joergen Bech | last post by:
Suppose I have Dim bm As New Bitmap(16, 16,Imaging.PixelFormat.Format8bppIndexed) I cannot use Dim g As Graphics = Graphics.FromImage(bmdest) Dim hdc As IntPtr = g.GetHdc() as the...
2
by: Peter Oliphant | last post by:
I want to create a new Bitmap which is a portion of an existing Bitmap. For example, if I have a Bitmap that is 100x100 in size I might want to create a new Bitmap that is equivalent to the one...
5
by: =?Utf-8?B?QVRU?= | last post by:
I have a bitmap of 100X100. On the load, the bitmap is created by a function (createimage()). On my OnPaint, I draw the image back to the screen (e.Graphics.DrawImage( bitmap, destrect)). Now,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.