1

I want to scan a page and save it automatically. This code works well but the problem is an image that creates and then it saves is too big! it creates an image with the size of 30Mb! How can I change this code to save an image with normal size? Here is my code:
Thanks.

        private void button7_Click(object sender, EventArgs e)
    {
        try
        {
            var deviceManager = new DeviceManager();

            for (int i = 1; i <= deviceManager.DeviceInfos.Count; i++) // Loop Through the get List Of Devices.
            {
                if (deviceManager.DeviceInfos[i].Type != WiaDeviceType.ScannerDeviceType) // Skip device If it is not a scanner
                {
                    continue;
                }
                lstListOfScanner.Items.Add(deviceManager.DeviceInfos[i].Properties["Name"].get_Value());
            }
        }
        catch (COMException ex)
        {
            MessageBox.Show(ex.Message);
        }

        try
        {
            var deviceManager = new DeviceManager();

            DeviceInfo AvailableScanner = null;

            for (int i = 1; i <= deviceManager.DeviceInfos.Count; i++) // Loop Through the get List Of Devices.
            {
                if (deviceManager.DeviceInfos[i].Type != WiaDeviceType.ScannerDeviceType) // Skip device If it is not a scanner
                {
                    continue;
                }

                AvailableScanner = deviceManager.DeviceInfos[i];

                break;
            }
            var device = AvailableScanner.Connect(); //Connect to the available scanner.
            var ScanerItem = device.Items[1]; // select the scanner.

            var imgFile = (ImageFile)ScanerItem.Transfer(FormatID.wiaFormatJPEG); //Retrive an image in Jpg format and store it into a variable.
            var Path = @"C:\....\ScanImg.jpg"; // save the image in some path with filename.
            if (File.Exists(Path))
            {
                File.Delete(Path);
            }
            imgFile.SaveFile(Path);
          }
        catch (COMException ex)
        {
            MessageBox.Show(ex.Message);
        }
        /////////////////////////////////////
    }
Laczkó Örs
  • 1,082
  • 1
  • 18
  • 38
Flash
  • 85
  • 10
  • I don't know how to add that code to my code. could ypu please add it? – Flash Sep 26 '19 at 10:12
  • Ok, you need to get an Image object from the ImageFile object before using [How to resize an Image C#](https://stackoverflow.com/questions/1922040/how-to-resize-an-image-c-sharp). What is the ScanerItem assembly ref? –  Sep 26 '19 at 10:22
  • ok,Thanks. it would be great if you could connect this two code :) i used using WIA; using System.Runtime.InteropServices; using System.Drawing; using System.IO; using System; – Flash Sep 26 '19 at 10:25
  • Look at the answer. –  Sep 26 '19 at 11:06
  • Where does `DeviceManager` comes from ? Do I need a reference or what ? – GuidoG Jun 18 '22 at 09:49

1 Answers1

2

Try this method to convert the raw scanned data:

public Bitmap GetBitmapFromRawData(int w, int h, byte[] data)
{
  Bitmap bmp = new Bitmap(w, h);
  int i = 0;
  for ( int y = 0; y < h; y++ )
  {
    for ( int x = 0; x < w; x++ )
    {
      int a = 255;
      // We have inverted red and blue to get the correct scanned image
      // else it is flipped up/down and right/left with bad colors
      int b = data[i];
      int g = data[i + 1];
      int r = data[i + 2];
      bmp.SetPixel(x, y, Color.FromArgb(a, r, g, b));
      i += 3;
    }
  }
  return bmp;
}

So your code is now:

private void button1_Click(object sender, EventArgs e)
{
  try
  {
    var deviceManager = new DeviceManager();

    for ( int i = 1; i <= deviceManager.DeviceInfos.Count; i++ ) // Loop Through the get List Of Devices.
    {
      if ( deviceManager.DeviceInfos[i].Type != WiaDeviceType.ScannerDeviceType ) // Skip device If it is not a scanner
      {
        continue;
      }
      lstListOfScanner.Items.Add(deviceManager.DeviceInfos[i].Properties["Name"].get_Value());
    }
  }
  catch ( COMException ex )
  {
    MessageBox.Show(ex.Message);
  }

  try
  {
    var deviceManager = new DeviceManager();

    DeviceInfo AvailableScanner = null;

    for ( int i = 1; i <= deviceManager.DeviceInfos.Count; i++ ) // Loop Through the get List Of Devices.
    {
      if ( deviceManager.DeviceInfos[i].Type != WiaDeviceType.ScannerDeviceType ) // Skip device If it is not a scanner
      {
        continue;
      }

      AvailableScanner = deviceManager.DeviceInfos[i];

      break;
    }
    var device = AvailableScanner.Connect(); //Connect to the available scanner.
    var ScanerItem = device.Items[1]; // select the scanner.

    var imgFile = (ImageFile)ScanerItem.Transfer();
    var data = (byte[])imgFile.FileData.get_BinaryData();
    var bitmap = GetBitmapFromRawData(imgFile.Width, imgFile.Height, data);

    var Path = @"C:\....\ScanImg.jpg"; // save the image in some path with filename.
    if ( File.Exists(Path) )
    {
      File.Delete(Path);
    }
    bitmap.Save(Path, ImageFormat.Jpeg);
  }
  catch ( COMException ex )
  {
    MessageBox.Show(ex.Message);
  }
  • thanks for the new code, but it doesn't work now. it has a problem only with: "data" on this line: var bitmap = GetBitmapFromRawData(imgFile.Width, imgFile.Height, data); There error is: it can not convert from 'object' to 'byte[]' How can i fix it? – Flash Sep 26 '19 at 12:41
  • I have re-pasted the code and added a useless cast in case but it should work if you copy the same method to replace the old in your code. –  Sep 26 '19 at 12:56
  • Thanks for the useful code. when i try it with new project, it worked but when i try with my project it showed me that error. i work on it more tomorrow and send my feed back – Flash Sep 26 '19 at 13:26
  • I only removed the `FormatID.wiaFormatJPEG` and added `var data =` and `var bitmap = ` and changed `imgFile.SaveFile` to `bitmap.Save`. –  Sep 26 '19 at 13:37
  • 1
    It works on my computer. Use `var data = (byte[])imgFile.FileData.get_BinaryData();` and check if the path to save file exists or create it else it causes a GDI+ exception... –  Sep 27 '19 at 08:07
  • You are wonderful! Thanks. Just one moe thing. I noticed the scanning image created with 180 degree rotation! How can i fix that to scan the paper normally? – Flash Sep 27 '19 at 08:47
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/200055/discussion-between-arash6657-and-olivier-rogier). – Flash Sep 27 '19 at 08:49
  • The image is normal with my scanner and your code. I found that: [How do I rotate a picture in WinForms](https://stackoverflow.com/questions/2163829/how-do-i-rotate-a-picture-in-winforms) –  Sep 27 '19 at 08:54
  • Dear Olivier, do you know why the code has problem with color scan images? it shows read when i scan blue page – Flash Oct 11 '19 at 07:51
  • I don't know. Do you have a sample? Have you changed some scanner parameters? If you scan using the Windows Device Tool (I use XnView to scan), have you the same problems with colors and rotation? You help me to discover WIA, so I'm not involved in and all works fine with my computer and my Canon. –  Oct 11 '19 at 08:14
  • 1
    When scanning black and white all is fine. I just do a try with colors (I used black and white the last time). Indeed, now the image is flipped up/down and right/left as you said, and colors are horrible : green are green but red are blue and blue are yellow/orange... It is really strange. I don't know WIA but there is a trouble with `GetBitmapFromRawData` so I inverted red and blue values, and now the image is perfect. Black & white remains good. Answer updated. Thanks. –  Oct 11 '19 at 10:23
  • perfect, thanks. i should still put this code:bmp.RotateFlip(RotateFlipType.Rotate180FlipX); It works perfect :) – Flash Oct 11 '19 at 10:54
  • When i press the button to start scanning, the windows form freezes and i can not move the form until the process will be finished! Does anyone know to where (how) can i write a Thread to release my form from freezing? Thanks in advance! – Flash Nov 14 '19 at 16:57
  • Dear Olivier, there is one more question if you have time :) i add a bool to continue the scanning proccess until the end. with your code it works well but with the other code that release the windows from freezing, it shows an error in last step. Could you please tell me where is the problem? Thanks – Flash Nov 18 '19 at 11:32
  • Where does DeviceManager comes from ? Do I need a reference or what ? – GuidoG Jun 18 '22 at 09:49