Bitmap和byte[]的相互轉換


        /// <summary>
        /// 將Bitmap轉換為字節數組
        /// </summary>
        /// <param name="width">圖像寬度</param>
        /// <param name="height">圖像長度</param>
        /// <param name="channel">圖像通道</param>
        /// <param name="img">原圖像</param>
        /// <returns></returns>
        public static byte[] getByteStreamFromBitmap(int width, int height, int channel, Bitmap img)
        {
            byte[] bytes = new byte[width * height * channel];
            BitmapData im = img.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, img.PixelFormat);
            int stride = im.Stride;
            int offset = stride - width * channel;
            int length = stride * height;
            byte[] temp = new byte[stride * height];
            Marshal.Copy(im.Scan0, temp, 0, temp.Length);
            img.UnlockBits(im);
            int posreal = 0;
            int posscan = 0;
            for (int c = 0; c < height; c++)
            {
                for (int d = 0; d < width * channel; d++)
                {
                    bytes[posreal++] = temp[posscan++];
                }
                posscan += offset;
            }
            return bytes;
        }

        /// <summary>  
        /// 將一個字節數組轉換為8bit灰度位圖  
        /// </summary>  
        /// <param name="rawValues">顯示字節數組</param>  
        /// <param name="width">圖像寬度</param>  
        /// <param name="height">圖像高度</param>  
        /// <returns>位圖</returns>  
        public static Bitmap ToGrayBitmap(byte[] rawValues, int width, int height)
        {
            //申請目標位圖的變量,並將其內存區域鎖定
            Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
            BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, width, height),
            ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);

            //獲取圖像參數
            int stride = bmpData.Stride;  // 掃描線的寬度  
            int offset = stride - width;  // 顯示寬度與掃描線寬度的間隙  
            IntPtr iptr = bmpData.Scan0;  // 獲取bmpData的內存起始位置  
            int scanBytes = stride * height;// 用stride寬度,表示這是內存區域的大小  

            //下面把原始的顯示大小字節數組轉換為內存中實際存放的字節數組
            int posScan = 0, posReal = 0;// 分別設置兩個位置指針,指向源數組和目標數組  
            byte[] pixelValues = new byte[scanBytes];  //為目標數組分配內存  

            for (int x = 0; x < height; x++)
            {
                //下面的循環節是模擬行掃描
                for (int y = 0; y < width; y++)
                {
                    pixelValues[posScan++] = rawValues[posReal++];
                }
                posScan += offset;  //行掃描結束,要將目標位置指針移過那段“間隙”  
            }

            //用Marshal的Copy方法,將剛才得到的內存字節數組復制到BitmapData中
            System.Runtime.InteropServices.Marshal.Copy(pixelValues, 0, iptr, scanBytes);
            bmp.UnlockBits(bmpData);  // 解鎖內存區域  

            //下面的代碼是為了修改生成位圖的索引表,從偽彩修改為灰度
            ColorPalette tempPalette;
            using (Bitmap tempBmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))
            {
                tempPalette = tempBmp.Palette;
            }
            for (int i = 0; i < 256; i++)
            {
                tempPalette.Entries[i] = Color.FromArgb(i, i, i);
            }

            bmp.Palette = tempPalette;

            //算法到此結束,返回結果
            return bmp;
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM