none
Twain tiff to bitmap RRS feed

Answers

  • No need to double post.  It's a hDib.  Copy a BitmapFileHeader to a stream and then copy the Dib.  Use new Bitmap(Stream) to get the bitmap.  Or copy the bits to scan0 of the Scan0 Bitmap Constructor.
    Friday, March 12, 2010 11:41 AM

All replies

  • I get tiff image handle frm twain. Now how should I convert it to Bitmap?

    static FromHbitmap doesnt work
    static internal FromGdiPlus also doesnt work


    .NET guy
    • Merged by SamAgain Monday, March 15, 2010 3:04 AM duplicated
    Friday, March 12, 2010 11:24 AM
  • No need to double post.  It's a hDib.  Copy a BitmapFileHeader to a stream and then copy the Dib.  Use new Bitmap(Stream) to get the bitmap.  Or copy the bits to scan0 of the Scan0 Bitmap Constructor.
    Friday, March 12, 2010 11:41 AM
  • Do you mean this Twain? If yes, you should ask on their forums. Their handle will be probably specific - do you have more information about it?

    -Karel

    Friday, March 12, 2010 5:02 PM
    Moderator
  • Do you mean this Twain? If yes, you should ask on their forums. Their handle will be probably specific - do you have more information about it?

    -Karel


    I dont think this is a good idea, because I managed TWAIN part to work. It gives me IntPtr for the scanned image. Now I cannot get Bitmap object from it. After digging on the net I think I found the right way. I will post it here , may be somebody else also needs such peace of code.
    .NET guy
    Saturday, March 13, 2010 9:13 AM
  • Why are you ignoring your duplicate post?  http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/5bc80ef3-18ab-4a0f-b308-b7346f68b46b.  What don't you understand?
    Saturday, March 13, 2010 9:30 AM
  • Hi, tsadigov:
         I merged your duplicated post to here. Could you let us know your progress?
    Please mark the right answer at right time.
    Thanks,
    Sam
    Monday, March 15, 2010 3:06 AM
  • I found a sample on the net which accepts IntPtr but that didnt work for me , I digged a little further and found that I should not pass that IntPrt directly I first shoul call another funtion and pass its return value.

    IntPtr bmpptr = Interop.Win32.GlobalLock(dibhand);//first this shoul be called
    
    Bitmap bmp= TwainHelper.BitmapFromDIB(bmpptr)


    but I dont know where to unlock this memory. At least this works. Heres the sample I found on the net.


    [StructLayout(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 void Init() { biSize = (uint)Marshal.SizeOf(this); }
        }
        class TwainHelper
        {
            private void SavehDibToTiff(int hDIB, string fileName, int xRes, int yRes)
            {
                //Identify the memory pointer to the DIB Handler (hDIB)  
                IntPtr dibPtr = new IntPtr(hDIB);
                //Save the contents of DIB pointer into bitmap object  
                Bitmap myBitmap = BitmapFromDIB(dibPtr);
                //Set resolution if needed  
                if (xRes > 0 && yRes > 0)
                    myBitmap.SetResolution(xRes, yRes);
                //Create an instance of the windows TIFF encoder  
                ImageCodecInfo ici = GetEncoderInfo("image/tiff");
                //Define encoder parameters  
                EncoderParameters eps = new EncoderParameters(1);
                // only one parameter in this case (compression)  
                //Create an Encoder Value for TIFF compression Group 4  
                long ev = (long)EncoderValue.CompressionCCITT4;
                eps.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, ev);
                //Save file                        
                myBitmap.Save(fileName, ici, eps);
            }
            //Helper to get Encoder from Windows for file type.
            private static ImageCodecInfo GetEncoderInfo(String mimeType)
            {
                ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
                for (int j = 0; j < encoders.Length; ++j)
                {
                    if (encoders[j].MimeType == mimeType)
                        return encoders[j];
                }
                return null;
            }
    
    
                   //THIS METHOD SAVES THE CONTENTS OF THE DIB POINTER INTO A BITMAP OBJECT
            internal static Bitmap BitmapFromDIB(IntPtr pDIB)
            {
                //get pointer to bitmap header info        
                IntPtr pPix = GetPixelInfo(pDIB);
                //Call external GDI method  
                MethodInfo mi = typeof(Bitmap).GetMethod("FromGDIplus", BindingFlags.Static | BindingFlags.NonPublic);
                if (mi == null)
                    return null;
                // Initialize memory pointer where Bitmap will be saved  
                IntPtr pBmp = IntPtr.Zero;
                //Call external methosd that saves bitmap into pointer  
                int status = GdipCreateBitmapFromGdiDib(pDIB, pPix, out pBmp);
                //If success return bitmap, if failed return null  
                if ((status == 0) && (pBmp != IntPtr.Zero))
                    return (Bitmap)mi.Invoke(null, new object[] { pBmp });
                else return null;
            }
            //THIS METHOD GETS THE POINTER TO THE BITMAP HEADER INFO
            private static IntPtr GetPixelInfo(IntPtr bmpPtr)
            {
                BITMAPINFOHEADER bmi = (BITMAPINFOHEADER)Marshal.PtrToStructure(bmpPtr, typeof(BITMAPINFOHEADER));
                if (bmi.biSizeImage == 0)
                    bmi.biSizeImage = (uint)(((((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3) * bmi.biHeight);
                int p = (int)bmi.biClrUsed; if ((p == 0) && (bmi.biBitCount <= 8))
                    p = 1 << bmi.biBitCount; p = (p * 4) + (int)bmi.biSize + (int)bmpPtr;
                return (IntPtr)p;
            }
            [DllImport("gdiplus.dll", ExactSpelling = true)]
            internal static extern int GdipCreateBitmapFromGdiDib(IntPtr bminfo, IntPtr pixdat, out IntPtr image);
    
           
        }






    .NET guy
    Monday, March 15, 2010 10:51 AM
  • No need to double post.  It's a hDib.  Copy a BitmapFileHeader to a stream and then copy the Dib.  Use new Bitmap(Stream) to get the bitmap.  Or copy the bits to scan0 of the Scan0 Bitmap Constructor.

    thanks for help

    can you help me to make this work? whats wrong in this sample?
    Sorry Im not so good at interop.

    int size = Marshal.SizeOf(typeof(BITMAPINFOHEADER));
    byte[] buff = new byte[size];
    Marshal.Copy(img, buff, 0,size);
    MemoryStream memstream = new MemoryStream(buff);
    Image bmp=Bitmap.FromStream(memstream);

    .NET guy
    Monday, March 15, 2010 11:11 AM
  • No need to double post.  It's a hDib.  Copy a Bitmap File Header to a stream and then copy the Dib.  Use new Bitmap(Stream) to get the bitmap.  Or copy the bits to scan0 of the Scan0 Bitmap Constructor.

    thanks for help

    can you help me to make this work? whats wrong in this sample?
    Sorry Im not so good at interop.

    int size = Marshal.SizeOf(typeof(BITMAPINFOHEADER));
    
    byte[] buff = new byte[size];
    
    Marshal.Copy(img, buff, 0,ize);
    
    MemoryStream memstream = new MemoryStream(buff);
    
    Image bmp=Bitmap.FromStream(memstream);
    
    

    .NET guy

    It's very long now, Who can give an answer?

    One of the parameters is incorrect.  The code's ok.
    Friday, September 3, 2010 5:26 AM