ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

/*
    Copyright (c) 2004 DigiTec Web Consultants, LLC.  All rights reserved.

    The use of this software is for test and performance purposes only.
    You may not use this software in any commercial applications without
    the express permission of the copyright holder.  You may add to or
    modify the code contained here-in to cause it to run slower without
    contacting the copyright holder, however, any attempts to make this
    code run faster should be documented on:
    
    http://weblogs.asp.net/justin_rogers/articles/131704.aspx
    
    I reserve the right to change or modify the publicly available version
    of this code at any time.  I will not provide version protection, so
    if you have reliance on a particular build of this software, then make
    your own back-ups.
   
    You must laugh, at least a little, when reading this licensing agreement,
    unless of course you don't have a sense of humor.  In all seriousness,
    excluding the laughter, laughter in itself does not void this license
    agreement, nor compromise it's ability to legally bind you.
   
    You must not remove this notice, or any other, from this software.
*/

/*
    Need some notes on use.  I previously published a blog entry describing
    this guy, but the end result was that unless you had already done some
    GDI+ work, my library would fail.  The reason it works in Windows Forms
    applications is because WinForms uses and initializes the library
    correctly before I get there.  However, try to load ImageFast stand-alone
    and all you get is a NullReferenceException.
   
    I'm past all of that now.  We correctly call GdiplusStartup and
    GdiplusShutdown (hopefully).  In addition, I've added more thorough image
    loading support by providing metafile loaders.
   
    To compile a release library:
        csc /t:library /optimize+ ImageFast.cs
       
    To compile a debug library with some console output:
        csc /t:library /debug+ /d:DEBUG,TRACE ImageFast.cs
       
    NOTE: This is now ready for ASP .NET users.  I've verified all of the
    different startup paths and shutdown paths to make sure there isn't
    anything strange with the libraries that would prevent them from
    running under ASP .NET without special tuning or instrumentation.
*/

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;

public class ImageFast {
    [DllImport("gdiplus.dll", ExactSpelling=true, CharSet=CharSet.Unicode)]
    private static extern int GdipLoadImageFromFile(string filename, out IntPtr image);
   
    [DllImport("gdiplus.dll", ExactSpelling=true, CharSet=CharSet.Unicode)]
    private static extern int GdiplusStartup(out IntPtr token, ref StartupInput input, out StartupOutput output);
   
    [DllImport("gdiplus.dll", ExactSpelling=true, CharSet=CharSet.Unicode)]
    private static extern int GdiplusShutdown(IntPtr token);

    [DllImport("gdiplus.dll", ExactSpelling=true, CharSet=CharSet.Unicode)]
    private static extern int GdipGetImageType(IntPtr image, out GdipImageTypeEnum type);
   
    private static IntPtr gdipToken = IntPtr.Zero;
   
    static ImageFast() {
#if DEBUG
        Console.WriteLine("Initializing GDI+");
#endif
        if ( gdipToken == IntPtr.Zero ) {
            StartupInput input = StartupInput.GetDefaultStartupInput();
            StartupOutput output;

            int status = GdiplusStartup(out gdipToken, ref input, out output);
#if DEBUG
            if ( status == 0 )
                Console.WriteLine("Initializing GDI+ completed successfully");
#endif
            if ( status == 0 )
                AppDomain.CurrentDomain.ProcessExit += new EventHandler(Cleanup_Gdiplus);
        }
    }
   
    private static void Cleanup_Gdiplus(object sender, EventArgs e) {
#if DEBUG
        Console.WriteLine("GDI+ shutdown entered through ProcessExit event");
#endif
        if ( gdipToken != IntPtr.Zero )
            GdiplusShutdown(gdipToken);

#if DEBUG
        Console.WriteLine("GDI+ shutdown completed");
#endif
    }
   
    private static Type bmpType = typeof(System.Drawing.Bitmap);
    private static Type emfType = typeof(System.Drawing.Imaging.Metafile);

    public static Image FromFile(string filename) {
        filename = Path.GetFullPath(filename);
        IntPtr loadingImage = IntPtr.Zero;
       
        // We are not using ICM at all, fudge that, this should be FAAAAAST!
        if ( GdipLoadImageFromFile(filename, out loadingImage) != 0 ) {
            throw new Exception("GDI+ threw a status error code.");
        }
       
        GdipImageTypeEnum imageType;
        if ( GdipGetImageType(loadingImage, out imageType) != 0 ) {
            throw new Exception("GDI+ couldn't get the image type");
        }
       
        switch(imageType) {
            case GdipImageTypeEnum.Bitmap:
                return (Bitmap) bmpType.InvokeMember("FromGDIplus", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[] { loadingImage });
            case GdipImageTypeEnum.Metafile:
                return (Metafile) emfType.InvokeMember("FromGDIplus", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[] { loadingImage });
        }
       
        throw new Exception("Couldn't convert underlying GDI+ object to managed object");
    }

    private ImageFast() { }
}

[StructLayout(LayoutKind.Sequential)]
internal struct StartupInput {
    public int GdiplusVersion;
    public IntPtr DebugEventCallback;
    public bool SuppressBackgroundThread;
    public bool SuppressExternalCodecs;
   
    public static StartupInput GetDefaultStartupInput() {
        StartupInput result = new StartupInput();
        result.GdiplusVersion = 1;
        result.SuppressBackgroundThread = false;
        result.SuppressExternalCodecs  = false;
        return result;
    }
}

[StructLayout(LayoutKind.Sequential)]
internal struct StartupOutput
{
    public IntPtr Hook;
    public IntPtr Unhook;
}

internal enum GdipImageTypeEnum {
    Unknown = 0,
    Bitmap = 1,
    Metafile = 2
}

Published Friday, May 14, 2004 12:36 AM by Justin Rogers

Comments

Friday, May 14, 2004 3:56 PM by TrackBack

# Wanting to fix all my past mistakes, here is an updated ImageFast library that doesn't rely on System.Drawing for init...

Monday, May 17, 2004 9:07 PM by TrackBack

# re: Using PInvoke with GDI just isn't an easy thing to do. System.Drawing.dll must have some *magic* I don't know about.

Tuesday, June 01, 2004 6:22 PM by TrackBack

# re: Fast Image Loading without asking for the hot-fix or waiting for the service pack...

Monday, June 07, 2004 12:52 PM by zjames

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

Thank you thank you thanks! Works great. Original wasn't working on Win2000 at home, then it DID work, WAS working at work on win2000, but today it wasn't... weird. This fix got it working again. Hopefully for all time. Thanks!
Zac James
Wednesday, March 04, 2009 11:48 AM by ...

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

Gute Arbeit hier! Gute Inhalte.

Thursday, March 12, 2009 4:50 AM by ...

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

Sehr wertvolle Informationen! Empfehlen!

Tuesday, December 08, 2009 12:18 AM by a_poostchi

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

Hi

I have a program that load a relatively large image file (satellite image), from a LAN.

To speed up loading process, I divide the original  image to smaller patches (e.g. 6x6 cm), and the application tile them appropriately. This works fine, but after each updated sat. image, I should divided it again, which is time consuming process.

I wonder how can I load desired patches from original image file?

Can you help me on this?

Thanks in advance.

# Windows Forms - C# Draw form components before showing the form

Pingback from  Windows Forms - C# Draw form components before showing the form

Sunday, January 02, 2011 6:49 AM by cemo

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

Hy justin and happy new year.I am a student

When I surfing last year on internet,I met your imagefast dll.I ve found it very cool.But When I test it in an thread it always close my aplication.I am not a very very expert on c#.Perhaps this error is coming from me.Also  if this error is corrected I would like to know how I can get it for commercial purpose.

Thankyou and  enjoy much in 2011....

Wednesday, May 04, 2011 5:10 AM by cheap clothes online

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

It sounds really amazing !I suppose if you like sports?I think choose right sporting clothes is very important!

Friday, May 13, 2011 1:40 AM by cooling pad

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

Happy to see your blog as it is just what I’ve looking for and excited to read all the posts. I am looking forward to another great article from you.myefox

Friday, May 13, 2011 1:47 AM by Apad

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

Happy to see your blog as it is just what I’ve looking for and excited to read all the posts. I am looking forward to another great article from you.myefox

Tuesday, May 24, 2011 9:26 PM by For iPhone 4

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

Thanks for sharing this nice post.I will keep your article in my idea.usbonlinegroup

Friday, June 10, 2011 10:36 PM by Wireless Keyboard

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

would you mind updating your blog with more information? It is extremely helpful for me.Keep it up.

Sunday, June 19, 2011 11:21 PM by tablette android

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

I like this post it is very good and informative. I am sure that this post will be very much helpful for people. Thanks for sharing!

Wednesday, June 22, 2011 3:53 AM by r4 ds

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

more and more please.

Thursday, July 07, 2011 12:00 PM by sears scratch and dent

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

Terrific work! This is the type of information that should be shared around the web. Shame on the search engines for not positioning this post higher!

Wednesday, August 10, 2011 12:03 AM by telephone double sim

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

Du tonnes de commentaires dans vos articles, je suppose que je ne suis pas le seul réel que possède tout le plaisir ici! Merci!

Friday, September 02, 2011 10:59 PM by grossiste en ligne

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

Ce fut un poste très agréable. Dans l'idée que je souhaite mettre en écrit, comme cette fois-ci ailleurs E prenant et des efforts réels pour faire un très bon article, mais ce que je peux dire que j'ai beaucoup tergiverser et certainement pas à obtenir une chose faite.

Tuesday, September 06, 2011 10:48 PM by grossiste en ligne

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

J'aime ce post, il est très bon et instructif. Je suis sûr que ce poste sera très utile pour les gens. Merci pour le partage!

Tuesday, September 06, 2011 11:30 PM by cosplay france

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

Septembre 06,2011

Vous cherchez un hélicoptère unique ? caractéristique ? Bon,je vous donne ce que vous voulez.

Tout va bien,pour un amateur de Avatar, je suis fasciné par les machines dans ce film. Surtout le hélicoptère,c’est excitant. Cool, si on peut s’asseoir à un hélicoptère,c’est magique. Mais c’est dans le reve,bien sur. La technologie ne peut pas arriver le niveau de la technologie dans le film. Il fera une route longue à rouler.

Mais la technoloige ne peut pas arriver,ne signifie qu’il ne peut pas arriver dans le Modèle. LEGO a fabirqué un Voiture rc qui est pareil comme le hélicoptère dans le film. Il ressemble au modèle original dans Avatar. On peut ouvrir la porte,et l’allumer, la hélice peut rouler. Mais on ne sais pas trop d’information sur le modèle,s’il vous intéresse, vous pouvez chercher des informations en ligne officiel ou myefox.Io offrit la voiture rc pas cher. Pour un Bateau RC,il est suffisant. Logo Avatar a fait bien.

C'est bien joli,ce hélicoptère RC,un cadeau pour l'enfant,surtout un garson.Le garcon est bien espiègle,on ne peut le satisfaire jamais

Thursday, September 08, 2011 11:08 PM by costume d'Halloween

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

C’est un grand festin pour les amateurs de WOW. C’est une guerre ‘’réelle ‘‘.Une ville BBrokeloh, Allemagne a accueilli plus de sept mille des amateurs de WOW. Ils peuvent s’habiller les vetements de cosplay ce qu’ils aiment beaucoup. Et échangent les goûts et les expériences propre. C’est une action la deuxième grande de cosplay dans le monde. On peut voir le conflit partout, les chevaliers battent les Nains,les Elfes battent les Orcs. C’est vraiment excitant.Un cosplay naruto.

Friday, September 16, 2011 5:06 AM by ephone

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

I was really looking for something like this.

It has helped me a lot, Keep it up, Thanks.

This is a good article worth watching,efox-shop

Friday, September 23, 2011 8:07 AM by fanjing3947@hotmail.com

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

I like your article here,keep updating.

Saturday, September 24, 2011 12:23 PM by OEM software online

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

med9eH I am getting married on the 15th of November. Congratulate me! Then will be here rarely!...

Sunday, September 25, 2011 2:53 PM by Cheap software online

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

2IY2Dy Author, Shoot yourself a knee..!

Thursday, October 06, 2011 10:12 PM by Tablet PC

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

Dies ist ein sehr guter Artikel.Es ist wunderbar, ich bin so gespannt, es zu benutzen!Freuen Sie sich auf Ihre unicode aktualisieren.

Sunday, October 09, 2011 10:05 PM by tablette android

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

Dans la compétition prochaine de Samsune et Apple, nous espérons qu’ils nous donnerons une nouvelletablette android extraordinaire.

Tuesday, October 25, 2011 10:22 PM by belstaff outlet

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

The teacher to students in order to prove smoking does harm, especially from the extraction of nicotine in cigarettes on the worm, and in a while, a worm died. The teacher then asked all: "you see, the experiment shows the???????" The classmates one answer: "don't smoke worms".

Friday, November 18, 2011 4:11 AM by wood plastic composite

# re: ImageFast: A stand-alone library for quickly loading GDI+ images without validation.

Nice work! It looks that you are highly expert blogger. Your post is an excellent example of why I keep coming back to read your excellent quality content that is forever updated. That was exactly what I needed to read today.

Wednesday, November 23, 2011 7:34 PM by Best way to draw thumbnails?

# Best way to draw thumbnails?

Pingback from  Best way to draw thumbnails?

Leave a Comment

(required) 
(required) 
(optional)
(required)