IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Mobile .NET Discussion :

Bitmap 1bpp (monochrome) en Compact Framework 3.5


Sujet :

Windows Mobile .NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Inscrit en
    Décembre 2009
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 4
    Par défaut Bitmap 1bpp (monochrome) en Compact Framework 3.5
    Bonjour,

    je souhaite convertir une bitmap 24bits en bitmap monochrome sous windows CE 5 (en CF 3.5) afin de l'envoyer vers une imprimante BT.

    j'utilise pour cela le code proposé ici : http://www.wischik.com/lu/programmer/1bpp.html

    ce code étant prévu à la base pour le Desktop, j'ai effectué des modifications (basiques) pour appeler les bonnes DLL en compact. Voici donc mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    #region ----------- DLL IMPORT -----------
            [DllImport("coredll.dll")]//
            public static extern bool DeleteObject(IntPtr hObject);
     
            [DllImport("coredll.dll")]
            public static extern IntPtr GetDC(IntPtr hwnd);
     
            [DllImport("coredll.dll")]//
            public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
     
            [DllImport("coredll.dll")]
            public static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);
     
            [DllImport("coredll.dll")]//
            public static extern int DeleteDC(IntPtr hdc);
     
            [DllImport("coredll.dll")]//
            public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
     
            [DllImport("coredll.dll")]//
            public static extern int BitBlt(IntPtr hdcDst, int xDst, int yDst, int w, int h, IntPtr hdcSrc, int xSrc, int ySrc, int rop);
            static int SRCCOPY = 0x00CC0020;
     
            [DllImport("coredll.dll")]//
            static extern IntPtr CreateDIBSection(IntPtr hdc, ref BITMAPINFO bmi, uint Usage, out IntPtr bits, IntPtr hSection, uint dwOffset);
            static uint BI_RGB = 0;
            static uint DIB_RGB_COLORS = 0;
            [StructLayout(LayoutKind.Sequential)]
            public struct BITMAPINFO
            {
                public uint biSize;
                public int biWidth, biHeight;
                public short biPlanes, biBitCount;
                public uint biCompression, biSizeImage;
                public int biXPelsPerMeter, biYPelsPerMeter;
                public uint biClrUsed, biClrImportant;
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
                public uint[] cols;
            }
     
            static uint MAKERGB(int r, int g, int b)
            {
                return ((uint)(b & 255)) | ((uint)((r & 255) << 8)) | ((uint)((g & 255) << 16));
            }
     
            #endregion
     
            /// <summary>
            /// Copies a bitmap into a 1bpp/8bpp bitmap of the same dimensions, fast
            /// </summary>
            /// <param name="b">original bitmap</param>
            /// <param name="bpp">1 or 8, target bpp</param>
            /// <returns>a 1bpp copy of the bitmap</returns>
            public static Bitmap CopyToBpp(Bitmap b, int bpp)
            {
                if (bpp != 1 && bpp != 8) throw new ArgumentException(@"1 or 8", "bpp");
     
                // Plan: built into Windows GDI is the ability to convert
                // bitmaps from one format to another. Most of the time, this
                // job is actually done by the graphics hardware accelerator card
                // and so is extremely fast. The rest of the time, the job is done by
                // very fast native code.
                // We will call into this GDI functionality from C#. Our plan:
                // (1) Convert our Bitmap into a GDI hbitmap (ie. copy unmanaged->managed)
                // (2) Create a GDI monochrome hbitmap
                // (3) Use GDI "BitBlt" function to copy from hbitmap into monochrome (as above)
                // (4) Convert the monochrone hbitmap into a Bitmap (ie. copy unmanaged->managed)
     
                int w = b.Width, h = b.Height;
                IntPtr hbm = b.GetHbitmap(); // this is step (1)
                //
                // Step (2): create the monochrome bitmap.
                // "BITMAPINFO" is an interop-struct which we define below.
                // In GDI terms, it's a BITMAPHEADERINFO followed by an array of two RGBQUADs
                BITMAPINFO bmi = new BITMAPINFO();
                bmi.biSize = 40;  // the size of the BITMAPHEADERINFO struct
                bmi.biWidth = w;
                bmi.biHeight = h;
                bmi.biPlanes = 1; // "planes" are confusing. We always use just 1. Read MSDN for more info.
                bmi.biBitCount = (short)bpp; // ie. 1bpp or 8bpp
                bmi.biCompression = BI_RGB; // ie. the pixels in our RGBQUAD table are stored as RGBs, not palette indexes
                bmi.biSizeImage = (uint)(((w + 7) & 0xFFFFFFF8) * h / 8);
                bmi.biXPelsPerMeter = 1000000; // not really important
                bmi.biYPelsPerMeter = 1000000; // not really important
                // Now for the colour table.
                uint ncols = (uint)1 << bpp; // 2 colours for 1bpp; 256 colours for 8bpp
                bmi.biClrUsed = ncols;
                bmi.biClrImportant = ncols;
                bmi.cols = new uint[256]; // The structure always has fixed size 256, even if we end up using fewer colours
                if (bpp == 1) { bmi.cols[0] = MAKERGB(0, 0, 0); bmi.cols[1] = MAKERGB(255, 255, 255); }
                else { for (int i = 0; i < ncols; i++) bmi.cols[i] = MAKERGB(i, i, i); }
                // For 8bpp we've created an palette with just greyscale colours.
                // You can set up any palette you want here. Here are some possibilities:
                // greyscale: for (int i=0; i<256; i++) bmi.cols[i]=MAKERGB(i,i,i);
                // rainbow: bmi.biClrUsed=216; bmi.biClrImportant=216; int[] colv=new int[6]{0,51,102,153,204,255};
                //          for (int i=0; i<216; i++) bmi.cols[i]=MAKERGB(colv[i/36],colv[(i/6)%6],colv[i%6]);
                // optimal: a difficult topic: http://en.wikipedia.org/wiki/Color_quantization
                // 
                // Now create the indexed bitmap "hbm0"
                IntPtr bits0; // not used for our purposes. It returns a pointer to the raw bits that make up the bitmap.
                IntPtr hbm0 = CreateDIBSection(IntPtr.Zero, ref bmi, DIB_RGB_COLORS, out bits0, IntPtr.Zero, 0);
                //
                // Step (3): use GDI's BitBlt function to copy from original hbitmap into monocrhome bitmap
                // GDI programming is kind of confusing... nb. The GDI equivalent of "Graphics" is called a "DC".
                IntPtr sdc = GetDC(IntPtr.Zero);       // First we obtain the DC for the screen
                // Next, create a DC for the original hbitmap
                IntPtr hdc = CreateCompatibleDC(sdc); SelectObject(hdc, hbm);
                // and create a DC for the monochrome hbitmap
                IntPtr hdc0 = CreateCompatibleDC(sdc); SelectObject(hdc0, hbm0);
                // Now we can do the BitBlt:
                BitBlt(hdc0, 0, 0, w, h, hdc, 0, 0, SRCCOPY);
                // Step (4): convert this monochrome hbitmap back into a Bitmap:
                Bitmap b0 = Image.FromHbitmap(hbm0);
                //
                // Finally some cleanup.
                DeleteDC(hdc);
                DeleteDC(hdc0);
                ReleaseDC(IntPtr.Zero, sdc);
                DeleteObject(hbm);
                DeleteObject(hbm0);
                //
                return b0;
            }
    J'obtiens malheureusement une exception de type "OutOfMemoryException" à la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Bitmap b0 = Image.FromHbitmap(hbm0);
    et ce quelque soit l'image de départ.

    J'ai augmenté la taille de la mémoire virtuelle de l'émulateur, ainsi que déployé ma solution directement sur la cible, sans succès.

    Une idée ?

    Merci.

  2. #2
    Membre à l'essai
    Inscrit en
    Décembre 2009
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 4
    Par défaut
    Problème résolu, j'ai simplement exécuté les opérations
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    DeleteDC(hdc);
                DeleteDC(hdc0);
                ReleaseDC(IntPtr.Zero, sdc);
                DeleteObject(hbm);
    avant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Bitmap b0 = Image.FromHbitmap(hbm0);
    , et tout s'exécute sans problème.
    j'ai cependant toujours des problèmes de compréhension quant à l'origine de l'erreur. J'ai en effet utilisé une image de faible taille (32*32*24bits) pour faire mes tests, la mémoire disponible n'aurait pas du être dépassée.
    bref si une personne compétente à une réponse à me donner je suis toujours preneur !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Bitmap framework 2.0 => Compact Framework
    Par haladiah dans le forum Windows Forms
    Réponses: 3
    Dernier message: 27/01/2010, 14h28
  2. pb compact framework .NET : format BITMAP
    Par Guntreg dans le forum C#
    Réponses: 1
    Dernier message: 06/09/2007, 17h42
  3. [C#][Compact Framework] [FAQ ?] afficher une image ressource
    Par chronos dans le forum Windows Forms
    Réponses: 1
    Dernier message: 13/07/2005, 18h24
  4. [VB.NET] PictureBox et Compact Framework
    Par WriteLN dans le forum Windows Forms
    Réponses: 6
    Dernier message: 10/03/2005, 10h03
  5. .NET Compact Framework et BDD ?
    Par gilou85 dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 23/02/2005, 14h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo