• 从文件或者字节数组中读取和复制Bitmap图像的安全方法


    大部分时候,我们使用下面代码来读取和复制bitmap文件

    Bitmap bmp = new Bitmap(fullpath);
    Bitmap bmpLoad = (Bitmap)bmp.Clone();
    Bmp.dispose(); //释放,避免锁定文件

    但是,clone会克隆文件流路径,这可能会带来问题。

    **********************************************************

    如果使用new Bitmap(bmp ),构造函数会使用屏幕dpi和32位PixelFormat来创建Bitmap,分辨率变成默认的96,图像深度会变成32。我们也不能使用memorystream来复制bitmap,因为图像需要在内存中保持数据流不被释放,这会带来内存管理的麻烦。

    可以这样写
    static Bitmap LoadImage(Stream stream)
    {
        Bitmap retval = null;

        using (Bitmap b = new Bitmap(stream))
        {
            retval = new Bitmap(b.Width, b.Height, b.PixelFormat);   //丢失分辨率,需要额外传参。
            using (Graphics g = Graphics.FromImage(retval))
            {
                g.DrawImage(b, Point.Empty);
                g.Flush();
            }
        }

        return retval;
    }

    **********************************************************

    比较安全的方法是使用LockBits+Marshal.Copy从内存中进行复制,这样可以确保深度不变。然后使用SetResolution设置分辨率。代码很长。
    参见https://stackoverflow.com/questions/4803935/free-file-locked-by-new-bitmapfilepath/7972963#7972963

    也可以试试下面的方法,使用ImageConverter类

    **********************************************************

    Using System.Drawing;
    private static readonly ImageConverter _imageConverter = new ImageConverter();

    图像到字节数组:

    /// <summary>
    /// Method to "convert" an Image object into a byte array, formatted in PNG file format, which
    /// provides lossless compression. This can be used together with the GetImageFromByteArray()
    /// method to provide a kind of serialization / deserialization.
    /// </summary>
    /// <param name="theImage">Image object, must be convertable to PNG format</param>
    /// <returns>byte array image of a PNG file containing the image</returns>
    public static byte[] CopyImageToByteArray(Image theImage)
    {
        using (MemoryStream memoryStream = new MemoryStream())
        {
            theImage.Save(memoryStream, ImageFormat.Png);   //更换成自己的格式,如果用RawFormat可能会出问题。

            return memoryStream.ToArray();
        }
    }


    字节数组到图像:

    /// <summary>
    /// Method that uses the ImageConverter object in .Net Framework to convert a byte array,
    /// presumably containing a JPEG or PNG file image, into a Bitmap object, which can also be
    /// used as an Image object.
    /// </summary>
    /// <param name="byteArray">byte array containing JPEG or PNG file image or similar</param>
    /// <returns>Bitmap object if it works, else exception is thrown</returns>
    public static Bitmap GetImageFromByteArray(byte[] byteArray)
    {
        Bitmap bm = (Bitmap)_imageConverter.ConvertFrom(byteArray);

        if (bm != null && (bm.HorizontalResolution != (int)bm.HorizontalResolution ||
        bm.VerticalResolution != (int)bm.VerticalResolution))
        {
            // Correct a strange glitch that has been observed in the test program when converting
            // from a PNG file image created by CopyImageToByteArray() - the dpi value "drifts"
            // slightly away from the nominal integer value
            bm.SetResolution((int)(bm.HorizontalResolution + 0.5f),  (int)(bm.VerticalResolution + 0.5f));
        }

        return bm;
    }

    使用示例:

    Bitmap newBitmap = GetImageFromByteArray(File.ReadAllBytes(fileName));
    这避免了与希望其源流保持打开的位图相关的问题,以及导致源文件保持锁定的一些建议的解决方法。

  • 相关阅读:
    HDU 2594 Simpsons’ Hidden Talents(辛普森一家的潜在天赋)
    HUD 2203 亲和串
    POJ 3461 Oulipo(乌力波)
    FJNU 1154 Fat Brother And His Love(胖哥与女神)
    Polygon Triangles
    Double it(水题模拟+逆向思维)
    Sphenic numbers(素数筛)
    Desktop(模拟)2016-2017 ACM Central Region of Russia Quarterfinal Programming Contest
    Weather Station(基础DP)2016-2017 ACM Central Region of Russia Quarterfinal Programming Contest
    找零钱(经典DP)
  • 原文地址:https://www.cnblogs.com/Charltsing/p/ReadandCopyBitmap.html
Copyright © 2020-2023  润新知