Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / January 2008

Tip: Looking for answers? Try searching our database.

breaking up bitmap images

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Stephen.Schoenberger@gmail.com - 14 Jan 2008 15:52 GMT
Hello,

I am reading in a bitmap image and storing it as a bitmap in C#. I
need to perform some mathmatical operations on that image but it needs
to be broken up into smaller fragments (16x16). On each of these
fragments I need to perform my work, then write back the manipulated
fragment to a new image. I have tried some different techniques but so
far no luck. Any advice would be great!

Thanks.
Nicholas Paldino [.NET/C# MVP] - 14 Jan 2008 16:08 GMT
Stephen,

   It should be easy enough.  First, you create a new Bitmap instance,
passing 16x16 to indicate you want a 16x16 image.  Once you have that, you
can pass the Bitmap to the static FromImage method on the Graphics class to
return a Graphics instance which will let you draw on the Bitmap.  Once you
have the Graphics instance, you can then call the DrawImage method on it,
passing the original image, and the section of the original image you want
to draw on your new, smaller image.

   Then you can perform your processing.

   Putting the images back together is just a matter of reversing the
process.  Create one image which is the size of all the smaller images, get
the Graphics instance for it, and then call DrawImage on the Graphics
instance, passing the smaller pieces and drawing them where appropriate.

Signature

         - Nicholas Paldino [.NET/C# MVP]
         - mvp@spam.guard.caspershouse.com

> Hello,
>
[quoted text clipped - 6 lines]
>
> Thanks.
Stephen.Schoenberger@gmail.com - 14 Jan 2008 21:33 GMT
On Jan 14, 11:08 am, "Nicholas Paldino [.NET/C# MVP]"
<m...@spam.guard.caspershouse.com> wrote:
> Stephen,
>
[quoted text clipped - 31 lines]
>
> > Thanks.

I am a little confused on how to use the DrawImage() for the use that
I need it...should I use Rectangle? Or PointF? Or another option????
Peter Duniho - 14 Jan 2008 22:30 GMT
> I am a little confused on how to use the DrawImage() for the use that
> I need it...should I use Rectangle? Or PointF? Or another option????

Whatever you want.

There are a lot of overloads for DrawImage().  Just find the one that  
suits your needs best.  For example:

    Bitmap[,] BitmapsFromBitmap(Bitmap bmpSrc, int cxDst, int cyDst)
    {
        int ccol = (bmpSrc.Width - 1) / cxDst + 1,
            crow = (bmpSrc.Height - 1) / cyDst + 1;
        Bitmap[,] rgbmpRet = new Bitmap[ccol][crow];

        for (int irow = 0; irow < crow; irow++)
        {
            for (int icol = 0; icol < ccol; icol++)
            {
                Bitmap bmpDst = new Bitmap(cxDst, cyDst);

                using (Graphics gfx = Graphics.FromImage(bmpDst))
                {
                    gfx.DrawImage(bmpSrc, 0, 0,
                        new Rectangle(icol * cxDst, irow * cyDst, cxDst,  
cyDst),
                        GraphicsUnit.Pixel);
                }

                rgbmpRet[icol, irow] = bmpDst;
            }
        }

        return rgbmpRet;
    }

Caveat: the above was just typed into the message...I didn't bother to try  
to compile or test it.  The code also makes no attempt to deal bitmaps  
that aren't an integral multiple of the size of the sub-bitmaps; if I  
recall correctly, if a source that isn't an integral multiple of the  
destination size is used, all that will happen is that the right and/or  
bottom edge of the last sub-bitmaps just won't be painted (they'll be  
black).

Finally, the above code assumes the passed in Bitmap is at least 1x1 pixel  
in size.

Pete
Stephen.Schoenberger@gmail.com - 23 Jan 2008 14:04 GMT
On Jan 14, 5:30 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
> > I am a little confused on how to use the DrawImage() for the use that
> > I need it...should I use Rectangle? Or PointF? Or another option????
[quoted text clipped - 43 lines]
>
> Pete

used your algorithm to attempt to solve this problem and upon the
program ending I have over 8200 files...i thought I would have 4800
files because I am using a 1280x960 image which is broken up into
16x16 blocks resulting in a 80x60 = 4800 images. Make sense? Any
further advice would be great. Here is the code that works...(your
code provided was close)

int ccol = (bmpSource.Width-1)/cxDst+1;
           int crow = (bmpSource.Height-1)/cyDst+1;

           Bitmap[,] ret = new Bitmap[ccol,crow];
           for (int irow = 0; irow < crow; irow++ )
           {
               for (int icol=0; icol < ccol; icol++)
               {
                   Bitmap bmpDst = new Bitmap(cxDst, cyDst);

                   using (Graphics gfx = Graphics.FromImage(bmpDst))
                   {
                       gfx.DrawImage(bmpSource, 0, 0, new
Rectangle(icol * cxDst, irow * cyDst, cyDst, cxDst),
GraphicsUnit.Pixel);
                   }
                   ret[icol, irow] = bmpDst;

                   //bmpDst.Save("bmpDst"+icol+"X"+irow+".bmp");
                   bmpDst.Save("bmpDst.bmp");
               }
           }
Peter Duniho - 23 Jan 2008 17:27 GMT
>  used your algorithm to attempt to solve this problem and upon the
> program ending I have over 8200 files...i thought I would have 4800
> files because I am using a 1280x960 image which is broken up into
> 16x16 blocks resulting in a 80x60 = 4800 images. Make sense? Any
> further advice would be great. Here is the code that works...(your
> code provided was close)

I don't see anything obviously wrong.  What filenames do you get when you  
use the version of Save() that embeds the row and column indices in the  
file name?  You can't have 8200 files and still have embedded indices that  
only range from "00X00" up to "79X59", so if in fact that loop is writing  
more than 4800 files (I really don't see how it could be), you should see  
filenames outside that range.

You should really be testing with a much small test file to start with.  
It's much easier to step through the entire algorithm, and to get a handle  
on exactly what's being written, when the number of tiles is small.  I'd  
recommend starting with something that only generates four to six tiles.  
That'd give you enough to watch several iterations, but not so many that  
watching _all_ the iterations would take prohibitively long.

Pete
Nicholas Paldino [.NET/C# MVP] - 14 Jan 2008 22:33 GMT
Stephen,

   I would use the overload specified here:

http://msdn2.microsoft.com/en-us/library/ms142040.aspx

   You just have to define the source and destination rectangles.  The
destination rectangle should be simple enough, it's just the rectangle that
defines the boundary of the whole image (the 16x16 image).

Signature

         - Nicholas Paldino [.NET/C# MVP]
         - mvp@spam.guard.caspershouse.com

> On Jan 14, 11:08 am, "Nicholas Paldino [.NET/C# MVP]"
> <m...@spam.guard.caspershouse.com> wrote:
[quoted text clipped - 41 lines]
> I am a little confused on how to use the DrawImage() for the use that
> I need it...should I use Rectangle? Or PointF? Or another option????
Stephen.Schoenberger@gmail.com - 23 Jan 2008 00:49 GMT
On Jan 14, 5:33 pm, "Nicholas Paldino [.NET/C# MVP]"
<m...@spam.guard.caspershouse.com> wrote:
> Stephen,
>
[quoted text clipped - 59 lines]
> > I am a little confused on how to use the DrawImage() for the use that
> > I need it...should I use Rectangle? Or PointF? Or another option????

I have started to figure this out but I have a new dilemma that has me
confused. With the image I need to split it up into 16x16 sub images
and SAVE the coordinates of each of those subimages (say sub image 1
goes from 0,0 to 15,15 or sub image 10 goes from 150,165 to
160,175...just arbitrary examples) perform the work on each subimage
then recombine the subimages (with work performed on them) to a new
output image. Any advice/help on this would be great.
Peter Duniho - 23 Jan 2008 01:28 GMT
> [...]
> I have started to figure this out but I have a new dilemma that has me
[quoted text clipped - 4 lines]
> then recombine the subimages (with work performed on them) to a new
> output image. Any advice/help on this would be great.

You'll either need to create a parallel data structure to contain the  
coordinate information or, probably better, create a new data structure  
that can contain both the image reference and the coordinate information.  
That way you can correlate the coordinates with each generated image.

As for recombining, it's pretty much the inverse of the splitting.  Create  
a Bitmap the size you need to contain all the pieces, then iterate through  
the pieces drawing each one into the destination bitmap.

Pete
Kevin Spencer - 23 Jan 2008 12:16 GMT
I had a similar problem. Here's how I solved it:

When saving the fragments, I simply give them a file name that contains the
coordinates of the fragment,combined with the name of the original file. For
example:

imageName

imageName_00
imageName_01
imageName_02

This way, I can work with multiple images and fragments from those images
concurrently. You can fetch the fragments using Directory.GetFiles, and a
wildcard containing the original image file name, and then parse the file
names to get their coordinates.

Signature

HTH,

Kevin Spencer
Chicken Salad Surgeon
Microsoft MVP

> On Jan 14, 5:33 pm, "Nicholas Paldino [.NET/C# MVP]"
> <m...@spam.guard.caspershouse.com> wrote:
[quoted text clipped - 78 lines]
> then recombine the subimages (with work performed on them) to a new
> output image. Any advice/help on this would be great.
Peter Duniho - 14 Jan 2008 21:22 GMT
> Hello,
>
[quoted text clipped - 4 lines]
> fragment to a new image. I have tried some different techniques but so
> far no luck. Any advice would be great!

In addition to what Nicholas wrote...

It sounds as though you want some sort of distributed processing to  
occur.  Depending on exactly how you're distributing the processing, you  
may find it better to use LockBits to create a single chunk of data that  
all the processors can operate on, and give each one a specific subset to  
use so that they don't conflict.

In particular, if all of this is happening within a single process, the  
overhead of copying all of those 16x16 subsets could be enough to  
significantly reduce or eliminate any advantages you might have gotten  
from parallelizing your algorithm.  Actually, it could do so even if the  
processing is being distributed to multiple processes or computers, but in  
that case the solution would be different (maybe use memory-mapped files  
for multiple processes...for multiple computers the only practical  
solution is likely to be to make the chunks of work larger than 16x16).

Pete

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.