Go Back   RunUO - Ultima Online Emulation > Developer's Corner > Programming > C#

C# C# Discussion

Reply
 
Thread Tools Display Modes
Old 01-06-2007, 09:34 PM   #1 (permalink)
Forum Expert
 
Join Date: Oct 2002
Age: 45
Posts: 4,366
Default Problem with Indexed Bitmaps

I'm writing a utility that converts map image files from Dragon format to Map Generator 2/UO Landscaper format.

I'm using a colormap to do the color conversion and it works great. But the problem I am having comes with saving the file. I'm having a problem saving the new file as an INDEXED bitmap. GDI+ doesn't seem to have any good methods built in for converting an image from true color to indexed bitmap.

I've played around with a few methods involving GetPixel but that is dog slow for these large bitmap files the program will be working with.

I've also tried this routine which I pulled from the web, it uses the GIF converter to convert from image to indexed bitmap. It is nice and fast, but the problem is that the resulting image comes out dithered, which makes it useless for my purposes.

Code:
        public static Image Image2Indexed8bpp(Image img)
        {
            System.IO.MemoryStream buffer = new System.IO.MemoryStream();
            img.Save(buffer, System.Drawing.Imaging.ImageFormat.Gif);
            buffer.Seek(0, System.IO.SeekOrigin.Begin);
            return Bitmap.FromStream(buffer);
        }

Anyone have any ideas on how to get around this shortcoming of GDI+?
HellRazor is online now   Reply With Quote
Old 01-06-2007, 09:50 PM   #2 (permalink)
Forum Expert
 
Join Date: Jul 2005
Location: Istanbul/Turkey
Age: 27
Posts: 425
Default

well i have no experience in this, but this article might help you to get what you need. it shows how to manipulate the data and save it also as indexed bmp.

http://www.codeproject.com/csharp/steganodotnet11.asp
__________________
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it."
noobie is offline   Reply With Quote
Old 01-08-2007, 12:55 PM   #3 (permalink)
ConnectUO Creator
 
Jeff's Avatar
 
Join Date: Jan 2004
Age: 28
Posts: 4,886
Default

Quote:
Originally Posted by HellRazor View Post
Anyone have any ideas on how to get around this shortcoming of GDI+?
I wouldnt call it a short coming, you need to learn to use pointers, the operation can be done very fast if you know how to use these, GetPixel and SetPixel use this but the reason it is slow is cause each time you use one of these operations it has to lock the bitmap into memory, do the method, then unlock it. In a sense, you yourself could do this with one lock if you learn how to manipulate bitmaps with pointers
__________________
Jeff Boulanger
ConnectUO - Core Developer

Want to help make ConnectUO better? Click here to submit your ideas/requests
Use your talent to compete against other community members in RunUO hosted coding competitions

If you know XNA (even if its just a little) or are a good artist(2d or 3d) and are interested in making games for a hobby send me a pm or drop by #xna in irc.runuo.com. I'm looking to put together a small game development team.


Please do not pm me for support. If you are having issues please post in the appropriate forum. Thanks for your continued support of both ConnectUO and RunUO
Jeff is offline   Reply With Quote
Old 01-08-2007, 12:59 PM   #4 (permalink)
Forum Expert
 
mordero's Avatar
 
Join Date: Nov 2003
Location: Illinois, USA
Age: 22
Posts: 2,911
Default

http://www.codersource.net/csharp_image_Processing.aspx

i think this will help you get started
mordero is offline   Reply With Quote
Old 01-08-2007, 01:19 PM   #5 (permalink)
Forum Expert
 
Join Date: Oct 2002
Age: 45
Posts: 4,366
Default

Quote:
Originally Posted by mordero View Post
http://www.codersource.net/csharp_image_Processing.aspx

i think this will help you get started

Thanks Modero, I had not come across this particular tutorial in my googling.
HellRazor is online now   Reply With Quote
Old 01-08-2007, 01:22 PM   #6 (permalink)
Forum Expert
 
Join Date: Oct 2002
Age: 45
Posts: 4,366
Default

Quote:
Originally Posted by Jeff View Post
I wouldnt call it a short coming, you need to learn to use pointers, the operation can be done very fast if you know how to use these, GetPixel and SetPixel use this but the reason it is slow is cause each time you use one of these operations it has to lock the bitmap into memory, do the method, then unlock it. In a sense, you yourself could do this with one lock if you learn how to manipulate bitmaps with pointers
Yeah, pointers are very much unexplored territory for me. I have found a few tutorials on using lock and unlock with graphics but it has been a little daunting.

I was really hoping for an easier solution but I'll do some checking into pointers/locking/unlocking - maybe I can figure it out. Undoubtedly it is probably the BEST way, I'm just not sure if I can figure it all out on my own without some help.

Thanks Jeff!
HellRazor is online now   Reply With Quote
Old 01-08-2007, 01:23 PM   #7 (permalink)
Forum Expert
 
Join Date: Oct 2002
Age: 45
Posts: 4,366
Default

Quote:
Originally Posted by noobie View Post
well i have no experience in this, but this article might help you to get what you need. it shows how to manipulate the data and save it also as indexed bmp.

http://www.codeproject.com/csharp/steganodotnet11.asp
Thanks noobie, this is helpful and I will check out the article.
HellRazor is online now   Reply With Quote
Old 01-22-2007, 01:22 PM   #8 (permalink)
Forum Expert
 
Join Date: Oct 2002
Age: 45
Posts: 4,366
Default

Ok, I've found some sample code that will do what I want. However, it only works correctly if the source image is a GIF file. My source image is a BMP file.

I'm pretty sure it has to do with the formula being used to scan through the source image, but I don't know the correct formula to use for a BMP image.

Can someone point me in the right direction?

Code:
Bitmap TerrainMap = (Bitmap)Image.FromFile(@"C:/test2.bmp");
ColorPalette cp = TerrainMap.Palette;
if(cp!=null) 
    { 

    //Create a new 8 bit per pixel image 

    Bitmap bm=new Bitmap(TerrainMap.Width, TerrainMap.Height, PixelFormat.Format8bppIndexed); 

    //get it's palette 

    ColorPalette ncp=bm.Palette; 

    //copy all the entries from the old palette removing any transparency 
  
    int n=0; 
    foreach(Color c in cp.Entries) 
       ncp.Entries[n++]=Color.FromArgb(255,c); 

      //re-insert the palette 

      bm.Palette=ncp; 

      //now to copy the actual bitmap data 

     //lock the source and destination bits 

     BitmapData src=((Bitmap)TerrainMap).LockBits(new Rectangle(0,0,TerrainMap.Width,TerrainMap.Height),ImageLockMode.ReadOnly,TerrainMap.PixelFormat); 

     BitmapData dst=bm.LockBits(new Rectangle(0,0,bm.Width,bm.Height),ImageLockMode.WriteOnly,bm.PixelFormat); 

    //uses pointers so we need unsafe code. 
    //the project is also compiled with /unsafe 

    unsafe 
    { 
       //steps through each pixel 

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

          //transferring the bytes 

          ((byte *)dst.Scan0.ToPointer())[(dst.Stride*y)+x]=((byte *)src.Scan0.ToPointer())[(src.Stride*y)+x]; 

        } 
    } 

   //all done, unlock the bitmaps 

   ((Bitmap)TerrainMap).UnlockBits(src); 
   bm.UnlockBits(dst); 
   TerrainMap.Dispose(); 

   //set the new image in place 

   TerrainMap=bm; 
   cp=TerrainMap.Palette; 
        TerrainMap.Save("C:/testbit.bmp", ImageFormat.Bmp);
    }
HellRazor is online now   Reply With Quote
Reply

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off



Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0 RC5