如何在c#中扫描图像并以正常大小保存

Posted

技术标签:

【中文标题】如何在c#中扫描图像并以正常大小保存【英文标题】:How to scan an image and save it with normal size in c# 【发布时间】:2020-01-26 13:21:45 【问题描述】:

我想扫描页面并自动保存。此代码运行良好,但问题是创建然后保存的图像太大!它会创建一个大小为 30Mb 的图像! 如何更改此代码以保存正常大小的图像? 这是我的代码: 谢谢。

        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);
        
        /////////////////////////////////////
    

【问题讨论】:

我不知道如何将该代码添加到我的代码中。可以请你添加它吗? 好的,在使用How to resize an Image C#之前需要从ImageFile对象中获取一个Image对象。什么是 ScanerItem 程序集参考? 好的,谢谢。如果您可以连接这两个代码,那就太好了:)我使用的是 WIA;使用 System.Runtime.InteropServices;使用 System.Drawing;使用 System.IO;使用系统; 看答案。 【参考方案1】:

试试这个方法来转换原始扫描数据:

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;

所以你的代码现在是:

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);
  

【讨论】:

感谢新代码,但它现在不起作用。它仅在以下行有问题:“数据”: var bitmap = GetBitmapFromRawData(imgFile.Width, imgFile.Height, data);错误是:它不能从 'object' 转换为 'byte[]' 我该如何解决? 我已经重新粘贴了代码并添加了一个无用的强制转换以防万一,但是如果您复制相同的方法来替换代码中的旧方法,它应该可以工作。 感谢您提供有用的代码。当我尝试使用新项目时,它可以工作,但是当我尝试使用我的项目时,它向我显示了该错误。我明天会做更多的工作并将我的反馈发回 它可以在我的电脑上运行。使用var data = (byte[])imgFile.FileData.get_BinaryData(); 并检查保存文件的路径是否存在或创建它,否则会导致 GDI+ 异常... 黑白扫描时一切正常。我只是尝试使用颜色(我上次使用的是黑白)。确实,现在图像像您所说的那样向上/向下和向右/向左翻转,颜色很可怕:绿色是绿色,但红色是蓝色,蓝色是黄色/橙色......这真的很奇怪。我不知道 WIA,但 GetBitmapFromRawData 有问题,所以我反转了红色和蓝色值,现在图像很完美。黑白照样不错。答案已更新。谢谢。

以上是关于如何在c#中扫描图像并以正常大小保存的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 saveFileDialog 在 C# 中保存图像? [复制]

如何使用 C# 将图像保存在数据库中 [关闭]

打开图像并使用相同的参数重新保存它,c#

如何在 C# 中的 WPF 应用程序中保存图像

C# 如何从存储在数据库中的 OLE 对象中保存图像

使用 c# 进行高质量 JPEG 压缩