C#圖片處理

  在軟體的世界中,經常需要做圖片的處理,這次在圖片優化的過程中,遇到了一些問題,索性趁著年節將這些資訊一併記錄下來

這次紀錄的東西大約有如下

  • Image/Bitmap轉byte、byte轉Image/Bitmap
  • 圖片縮圖
  • 清除圖片資訊
  • PNG轉JPG背景透明

Image/Bitmap轉byte、byte轉Image/Bitmap

        /// <summary>
        /// Bitmap轉byte
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        public static byte[] ToByte(Bitmap bitmap)
        {
            byte[] bytes = null;
            using (MemoryStream oMemoryStream = new MemoryStream())
            {
                using (Bitmap oBitmap = new Bitmap(bitmap))
                {
                    oBitmap.Save(oMemoryStream, ImageFormat.Jpeg);
                    oMemoryStream.Position = 0;
                    bytes = new byte[oMemoryStream.Length];
                    oMemoryStream.Read(bytes, 0, Convert.ToInt32(oMemoryStream.Length));
                    oMemoryStream.Flush();
                }
            }

            return bytes;
        }

        /// <summary>
        /// Image轉byte
        /// </summary>
        /// <param name="img"></param>
        /// <returns></returns>
        public static byte[] ToByte(Image img)
        {
            byte[] bytes = null;
            using (MemoryStream oMemoryStream = new MemoryStream())
            {
                img.Save(oMemoryStream, ImageFormat.Jpeg);
                oMemoryStream.Position = 0;
                bytes = new byte[oMemoryStream.Length];
                oMemoryStream.Read(bytes, 0, Convert.ToInt32(oMemoryStream.Length));
                oMemoryStream.Flush();
            }

            return bytes;
        }

        /// <summary>
        /// byte轉成bitmap
        /// </summary>
        /// <param name="byteArray">bytes</param>
        /// <returns>Image</returns>
        public static Bitmap ByteArrayToBitmap(byte[] byteArray)
        {
            Bitmap bmp;
            using (MemoryStream ms = new MemoryStream(byteArray))
            {
                bmp = new Bitmap(ms);
            }
            return bmp;
        }

        /// <summary>
        /// byte轉成image
        /// </summary>
        /// <param name="byteArray">bytes</param>
        /// <returns>Image</returns>
        private Image ByteArrayToImage(byte[] byteArray)
        {
            MemoryStream ms = new MemoryStream(byteArray);
            Image image = Image.FromStream(ms);
            return image;
        }

圖片縮圖

        /// <summary>
        /// 縮圖
        /// </summary>
        /// <param name="multiple">縮圖倍數</param>
        /// <returns></returns>
        public Bitmap Shrink(Bitmap bitmap, int multiple)
        {
            bitmap = (Bitmap)bitmap.GetThumbnailImage(bitmap.Width / multiple, bitmap.Height / multiple, null, IntPtr.Zero);
            return bitmap;
        }

清除圖片資訊

        public void RemovePropertyItem(Bitmap _bitmap)
        {
            foreach (PropertyItem item in _bitmap.PropertyItems)
            {
                item.Id = 0;
                item.Value = null;
            }
        }

PNG轉JPG背景透明

其實整篇文章最妙的地方就在這個章節了,由於先前做了種種手段增進前台載入圖片的速度,如清除圖片資訊、採用漸進式圖片

在這些功能在後台設定完畢後,卻在一次機緣下發現有一些問題存在...

在後台將PNG帶有透明背景上傳時,背景透明之處會被轉為黑色在當下的第一個反應是JPG圖檔本身就沒有透明背景的功能,此時前台開發人員卻告知即便上傳透明背景的PNG圖檔被轉成JPG,依舊有透明背景的功能。

這時我懵了,PNG轉成JPG後仍保有背景透明?這到底是什麼妖魔鬼怪的技術,上網查了一下資料才知道,現在的瀏覽器,是不認圖片副檔名的,只要上傳的是圖檔,存成JPG、GIF、PNG、通通沒有差瀏覽器是以二進位制讀取圖片的。

因此,這次在壓縮圖片、清除圖片資訊時,導致二進制資料真的是JPG圖片了,自然而然的就會有背景顏色了。

 

既然如此,直接將圖片存成PNG不就得了?那可不行!

因為PNG儲存時檔案預設會比JPG大,故還是偏向採用JPG圖檔作為儲存。

既然如此,那該怎麼解決呢?

有二種解決的方式,都必須先將圖片轉成Bitmap類別

解法1:直接將圖片背景設為透明

Bitmap.MakeTransparent()

解法2:設定圖片背景顏色

MakeTransparent(Color)

如此就大功告成啦!


LINE討論群FB討論區

歡迎您的加入,讓這個社群更加美好!

聯絡方式:
FaceBook
E-Mail