使用Twain释放图像消耗的内存

时间:2016-04-28 02:37:51

标签: c# c++ visual-studio memory-leaks twain

Twain将图像扫描到内存并消耗太多内存。所以我批量扫描图像,并在内存中压缩图像。因此应该发布源图像。我怎么能这样做?

public static BitmapSource FormHDib(IntPtr dibHandle)
        {
            BitmapSource bs = null;
            IntPtr bmpPtr = IntPtr.Zero;
            bool flip = true; // vertivcally flip the image

            try {
                bmpPtr = Win32.GlobalLock(dibHandle);
                Win32.BITMAPINFOHEADER bmi = new Win32.BITMAPINFOHEADER();
                Marshal.PtrToStructure(bmpPtr, bmi);

                if (bmi.biSizeImage == 0)
                    bmi.biSizeImage = (uint)(((((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3) * bmi.biHeight);

                int palettSize = 0;

                if (bmi.biClrUsed != 0)
                    throw new NotSupportedException("DibToBitmap: DIB with pallet is not supported");

                // pointer to the beginning of the bitmap bits
                IntPtr pixptr = (IntPtr)((int)bmpPtr + bmi.biSize + palettSize);

                // Define parameters used to create the BitmapSource.
                PixelFormat pf = PixelFormats.Default;
                switch (bmi.biBitCount) {
                    case 32:
                        pf = PixelFormats.Bgr32;
                        break;
                    case 24:
                        pf = PixelFormats.Bgr24;
                        break;
                    case 8:
                        pf = PixelFormats.Gray8;
                        break;
                    case 1:
                        pf = PixelFormats.BlackWhite;
                        break;
                    default:   // not supported
                        throw new NotSupportedException("DibToBitmap: Can't determine picture format (biBitCount=" + bmi.biBitCount + ")");
                    // break;
                }
                int width = bmi.biWidth;
                int height = bmi.biHeight;
                int stride = (int)(bmi.biSizeImage / height);
                byte[] imageBytes = new byte[stride * height];

                //Debug: Initialize the image with random data.
                //Random value = new Random();
                //value.NextBytes(rawImage);

                if (flip) {
                    for (int i = 0, j = 0, k = (height - 1) * stride; i < height; i++, j += stride, k -= stride)
                        Marshal.Copy(((IntPtr)((int)pixptr + j)), imageBytes, k, stride);
                } else {
                    Marshal.Copy(pixptr, imageBytes, 0, imageBytes.Length);
                }

                int xDpi = (int)Math.Round(bmi.biXPelsPerMeter * 2.54 / 100); // pels per meter to dots per inch
                int yDpi = (int)Math.Round(bmi.biYPelsPerMeter * 2.54 / 100);

                // Create a BitmapSource.
                bs = BitmapSource.Create(width, height, xDpi, yDpi, pf, null, imageBytes, stride);
                Win32.GlobalUnlock(pixptr);
                Win32.GlobalFree(pixptr);
            } catch (Exception ex) {
                string msg = ex.Message;
            }
            finally {
                // cleanup
                if (bmpPtr != IntPtr.Zero) { // locked sucsessfully
                    Win32.GlobalUnlock(dibHandle);
                }
            }
            Win32.GlobalUnlock(bmpPtr);
            Win32.GlobalFree(bmpPtr);

            return bs;
        }

生成BitSource

internal static System.Windows.Media.ImageSource compressImage(System.Windows.Media.ImageSource ims)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                using (MemoryStream outS = new MemoryStream())
                {
                    BitmapSource bs = ims as BitmapSource;
                    JpegBitmapEncoder encoder = new JpegBitmapEncoder();
                    BitmapFrame bf = BitmapFrame.Create(bs);
                    //encoder.Frames.Add(BitmapFrame.Create(image1.Source));
                    encoder.Frames.Add(bf);
                    encoder.Save(stream);
                    stream.Flush();

                    try
                    {
                        // Read first frame of gif image
                        using (MagickImage image = new MagickImage(stream))
                        {
                            image.Quality = 75;
                            image.Resize(new Percentage(0.65));
                            image.Density = new Density(200, DensityUnit.PixelsPerInch);
                            image.Write(outS);
                            image.Dispose();
                        }

                        stream.Close();
                        stream.Dispose();
                        BitmapImage bitmap = new BitmapImage();
                        bitmap.BeginInit();
                        bitmap.CacheOption = BitmapCacheOption.OnLoad;
                        outS.Position = 0;
                        bitmap.StreamSource = outS;
                        //
                        bitmap.EndInit();
                        //bitmap.Freeze();
                        outS.Flush();
                        outS.Close();
                        outS.Dispose();
                        ims = null;
                        return bitmap;
                    }
                    catch (Exception e)
                    {
                        return null;
                    }
                }
            }

        }

压缩内存中的图像

{{1}}

0 个答案:

没有答案