Results 1 to 11 of 11

Thread: [RESOLVED] PInvoke, SetDIBitsToDevice, parameter [In]

  1. #1

    Thread Starter
    Smitten by reality Harsh Gupta's Avatar
    Join Date
    Feb 2005
    Posts
    2,938

    Resolved [RESOLVED] PInvoke, SetDIBitsToDevice, parameter [In]

    Hi, please check the following link:

    http://www.pinvoke.net/default.aspx/...sToDevice.html

    What does [In] keyword in parameter ref BITMAPINFO means? How do you use it? When calling this function, how to pass this particular parameter?

    I have been trying to use this API for about 3 weeks, and everytime I get Invalid paramter error.
    Show Appreciation. Rate Posts.

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: PInvoke, SetDIBitsToDevice, parameter [In]

    That isn't actually part of C#. As far as I'm aware that indicates an input parameter in the C++ documentation. I'm guessing that it's used there to indicate that, even though the C# parameter is marked 'ref' it is still only for input purposes and not output. Usually you'd assume that a 'ref' parameter was going to have it's value changed by the method call but, if you check the MSDN documentation for the SetDIBitsToDevice function, you'll see that that parameter is a pointer marked as input.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  3. #3

    Thread Starter
    Smitten by reality Harsh Gupta's Avatar
    Join Date
    Feb 2005
    Posts
    2,938

    Re: PInvoke, SetDIBitsToDevice, parameter [In]

    Thanks.

    So, is there any way to determine as to which parameter is incorrect? I get this error while invoking this function. I presume it must be the BITMAPINFO parameter.
    Show Appreciation. Rate Posts.

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: PInvoke, SetDIBitsToDevice, parameter [In]

    Show us the exact code you're using, including your definition of that structure.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  5. #5

    Thread Starter
    Smitten by reality Harsh Gupta's Avatar
    Join Date
    Feb 2005
    Posts
    2,938

    Re: PInvoke, SetDIBitsToDevice, parameter [In]

    APIs
    Code:
    public static class PrintImage
        {
            public struct PALETTEENTRY
            {
                public byte peRed;
                public byte peGreen;
                public byte peBlue;
                public byte peFlags;
            }
            [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential, Pack=1)]
            public struct BITMAPINFOHEADER
            {
                public uint biSize;
                public int biWidth;
                public int biHeight;
                public ushort biPlanes;
                public ushort biBitCount;
                public uint biCompression;
                public uint biSizeImage;
                public int biXPelsPerMeter;
                public int biYPelsPerMeter;
                public uint biClrUsed;
                public uint biClrImportant;
            }
            public struct BITMAPINFO
            {
                public BITMAPINFO(BITMAPINFOHEADER bmiHeader)
                {
                    this.bmiHeader = bmiHeader;
                    bmiColors = new PALETTEENTRY[0];
                }
                public BITMAPINFOHEADER bmiHeader;
                public PALETTEENTRY[] bmiColors;
            }
    
            public const int BI_RGB = 0;
            public const int DIB_RGB_COLORS = 0;
    
            [System.Runtime.InteropServices.DllImport("gdi32.dll")]
            public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
    
            [System.Runtime.InteropServices.DllImport("gdi32.dll")]
            public static extern int SetDIBitsToDevice(IntPtr hDC, int DestX, int DestY, uint wDestWidth, uint wDestHeight, int SrcX, int SrcY, uint uStartScan, uint uScanLines, byte[] lpBits, ref BITMAPINFO BitsInfo, uint uColorUse);
        }
    There's more to it, I created this class using this as an example.

    I am trying to display an image file SGI format (.rgb extension) into a picturebox. I am calling it on a button click (I also tried to call this on picturebox paint event)
    Code:
    try
                {
                    byte[] data = System.IO.File.ReadAllBytes("test.rgb");
    
                    byte[] data3 = (new ReadImage(ref data)).ReadChannels();
    
                    PrintImage.BITMAPINFOHEADER bmiHeader = new PrintImage.BITMAPINFOHEADER();
                    bmiHeader.biSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(bmiHeader);
                    bmiHeader.biWidth = 400;
                    bmiHeader.biHeight = -400;
                    //bmiHeader.biPlanes = 1;
                    bmiHeader.biBitCount = 32;
                    //bmiHeader.biClrUsed = 0;
                    //bmiHeader.biClrImportant = 0;
                    bmiHeader.biCompression = PrintImage.BI_RGB;
                    bmiHeader.biSizeImage = 400 * 400;
    
                    PrintImage.BITMAPINFO bmi = new PrintImage.BITMAPINFO(bmiHeader);
    
                    IntPtr lhDC = PrintImage.CreateCompatibleDC(PrintImage.GetWindowDC(pictureBox1.Handle));
    
                    int test = PrintImage.SetDIBitsToDevice(lhDC, 0, 0, 400, 400, 0, 0, 0, 400, data3, ref bmi, PrintImage.DIB_RGB_COLORS);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                    return;
                }
    ReadChannels function is:
    Code:
    public class ReadImage
        {
            private byte[] imageByteData;
            public ReadImage(ref byte[] imageByteData)
            {
                this.imageByteData = imageByteData;
            }
    
            public byte[] ReadChannels()
            {
                byte[] channelData = new byte[400 * 400 * 4];
                for (int count = 0; count < 400 * 400; count++)
                {
                    channelData[4 * count] = imageByteData[count + 400 * 400 * 2];
                    channelData[4 * count + 1] = imageByteData[count + 400 * 400];
                    channelData[4 * count + 2] = imageByteData[count];
                    channelData[4 * count + 3] = 0;
                }
    
                return channelData;
            }
        }
    The file doesn't have a header information (in the file I mean) and I also tried with Bitcount set to 24 and omitted the reserved flag byte from the PaletteEntry struct. Same error.
    Show Appreciation. Rate Posts.

  6. #6
    Ex-Super Mod RobDog888's Avatar
    Join Date
    Apr 2001
    Location
    LA, Calif. Raiders #1 AKA:Gangsta Yoda™
    Posts
    60,709

    Re: PInvoke, SetDIBitsToDevice, parameter [In]

    Try checlking out the reference info in these three links. There is more depth to this then what pinvoke has.

    http://msdn.microsoft.com/en-us/libr...74(VS.85).aspx
    http://msdn.microsoft.com/en-us/libr...75(VS.85).aspx
    http://msdn.microsoft.com/en-us/libr...38(VS.85).aspx
    VB/Office Guru™ (AKA: Gangsta Yoda®)
    I dont answer coding questions via PM. Please post a thread in the appropriate forum.

    Microsoft MVP 2006-2011
    Office Development FAQ (C#, VB.NET, VB 6, VBA)
    Senior Jedi Software Engineer MCP (VB 6 & .NET), BSEE, CET
    If a post has helped you then Please Rate it!
    Reps & Rating PostsVS.NET on Vista Multiple .NET Framework Versions Office Primary Interop AssembliesVB/Office Guru™ Word SpellChecker™.NETVB/Office Guru™ Word SpellChecker™ VB6VB.NET Attributes Ex.Outlook Global Address ListAPI Viewer utility.NET API Viewer Utility
    System: Intel i7 6850K, Geforce GTX1060, Samsung M.2 1 TB & SATA 500 GB, 32 GBs DDR4 3300 Quad Channel RAM, 2 Viewsonic 24" LCDs, Windows 10, Office 2016, VS 2019, VB6 SP6

  7. #7

    Thread Starter
    Smitten by reality Harsh Gupta's Avatar
    Join Date
    Feb 2005
    Posts
    2,938

    Re: PInvoke, SetDIBitsToDevice, parameter [In]

    Thanks. I have already checked those links. In fact, my code is mostly modified based on the information contained in those links.
    Show Appreciation. Rate Posts.

  8. #8
    Ex-Super Mod RobDog888's Avatar
    Join Date
    Apr 2001
    Location
    LA, Calif. Raiders #1 AKA:Gangsta Yoda™
    Posts
    60,709

    Re: PInvoke, SetDIBitsToDevice, parameter [In]

    But did you go through all the info?

    A DIB consists of two distinct parts: a BITMAPINFO structure describing the dimensions and colors of the bitmap, and an array of bytes defining the pixels of the bitmap. The bits in the array are packed together, but each scan line must be padded with zeroes to end on a LONG data-type boundary. If the height of the bitmap is positive, the bitmap is a bottom-up DIB and its origin is the lower-left corner. If the height is negative, the bitmap is a top-down DIB and its origin is the upper left corner.

    A bitmap is packed when the bitmap array immediately follows the BITMAPINFO header. Packed bitmaps are referenced by a single pointer. For packed bitmaps, the biClrUsed member must be set to an even number when using the DIB_PAL_COLORS mode so that the DIB bitmap array starts on a DWORD boundary.
    Also, you have biPlanes commented but should be set to 1
    //bmiHeader.biPlanes = 1;

    Do you have your biBitCount set correctly as per your image?
    VB/Office Guru™ (AKA: Gangsta Yoda®)
    I dont answer coding questions via PM. Please post a thread in the appropriate forum.

    Microsoft MVP 2006-2011
    Office Development FAQ (C#, VB.NET, VB 6, VBA)
    Senior Jedi Software Engineer MCP (VB 6 & .NET), BSEE, CET
    If a post has helped you then Please Rate it!
    Reps & Rating PostsVS.NET on Vista Multiple .NET Framework Versions Office Primary Interop AssembliesVB/Office Guru™ Word SpellChecker™.NETVB/Office Guru™ Word SpellChecker™ VB6VB.NET Attributes Ex.Outlook Global Address ListAPI Viewer utility.NET API Viewer Utility
    System: Intel i7 6850K, Geforce GTX1060, Samsung M.2 1 TB & SATA 500 GB, 32 GBs DDR4 3300 Quad Channel RAM, 2 Viewsonic 24" LCDs, Windows 10, Office 2016, VS 2019, VB6 SP6

  9. #9

    Thread Starter
    Smitten by reality Harsh Gupta's Avatar
    Join Date
    Feb 2005
    Posts
    2,938

    Re: PInvoke, SetDIBitsToDevice, parameter [In]

    Quote Originally Posted by RobDog888 View Post
    But did you go through all the info?



    Also, you have biPlanes commented but should be set to 1
    //bmiHeader.biPlanes = 1;

    Do you have your biBitCount set correctly as per your image?
    Yeah. You won't believe me, but the same approach is working on VC++. I got that code from someone (I think it was VC++ 6 code, and I converted it into VC++ 2008. The only difference was that instead of byte array, I used unsigned char array to store data of file.

    The biPlanes made no diffference, and since I am using DIB_RGB_COLORS, biClrUsed and likes are irrelevant in my case.
    Show Appreciation. Rate Posts.

  10. #10

    Thread Starter
    Smitten by reality Harsh Gupta's Avatar
    Join Date
    Feb 2005
    Posts
    2,938

    Re: PInvoke, SetDIBitsToDevice, parameter [In]

    Another question.

    Is there any C# equivalent for memset() function? Any function available in Marshal class?
    Show Appreciation. Rate Posts.

  11. #11

    Thread Starter
    Smitten by reality Harsh Gupta's Avatar
    Join Date
    Feb 2005
    Posts
    2,938

    Re: PInvoke, SetDIBitsToDevice, parameter [In]

    OK, I solved the problem right now by using Bitmap class and using SetPixel() and GetPixel() functions.

    Loop through Height (outer) and Width (inner), and (if you look at the code posted in first post, I created a byte array named data3) use this array to set pixel at (x, y) position.

    Code:
    Create Bitmap object for width, height
    for y from 0 to height - 1
    {
        for x from 0 to width - 1
        {
            create R, G, B separately, from data3 array
            now how this data is arranged in data3, look for details below after code block
            create Color object using these RGB values
            Create pixel for declared bitmap using SetPixel(x, y, COLOR(R, G, B));
        }
    }
    Hope this helps.

    How SGI format (.rgb) files are ordered

    Details for SGI format can be found here

    Though I was not reading header information from the file, nor do they have one, I can explain as to how the data in file looks like.

    As the name suggests, this file consists of image data in RGB format, where each color/channel gets 8 bits each per pixel, thus, creating a pixel which is 24-bits long. Though, you can add Alpha channel and make a pixel 32 bit long, but it is not required.

    The data in file consists of 3 parts, the first part consist of all RED data, second part with all GREEN data and finally 3rd part with all BLUE data. In this format, knowledge of height and width of image is required beforehand because only then you will be able to create the pixels accordingly. If header is not specified, which consists of height and width, you must know the size of image explicitly. General rule, if height is h, and width is w, size of RED, GREEN and BLUE data individually will be h*w. So, if you read R value at 0 location of data, the corresponding G data will be at h*w location and B data will be at h*w*2 location.

    You pick up these 3 values from respective location, and create a pixel and so forth.

    I will post a more explaining code here asap.

    Thanks for your help jmc and RD.

    Though, I would still like to know, why the BITMAPINFO API was not working. The only difference was that I was using memset() function on BitmapInfo object bmi.

    Resolved for now.
    Show Appreciation. Rate Posts.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width