1. 程式人生 > >PictureBox空間繫結類,通過函式控制顯示與重新整理,開啟雙緩衝

PictureBox空間繫結類,通過函式控制顯示與重新整理,開啟雙緩衝

巧用GDI32.Dll做控制元件繫結 與 影象重新整理

開啟雙緩衝,如下程式碼所示

 SetStyle(
                     ControlStyles.OptimizedDoubleBuffer
                     | ControlStyles.ResizeRedraw
                     | ControlStyles.Selectable
                     | ControlStyles.AllPaintingInWmPaint
                     | ControlStyles.UserPaint
                     | ControlStyles.SupportsTransparentBackColor,
                     true);  

這裡我們新建一個類,叫Gxbitmap

using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.IO;
using GxIAPINET;

namespace daheng_xkk
{
    public class GxBitmap
    {

        IGXDevice m_objIGXDevice = null;                ///<裝置對像
        PictureBox m_pic_ShowImage = null;                ///<圖片顯示控制元件
        bool m_bIsColor = false;               ///<是否支援彩色相機
        byte[] m_byMonoBuffer = null;                ///<黑白相機buffer
        byte[] m_byColorBuffer = null;                ///<彩色相機buffer
        byte[] m_byRawBuffer = null;                ///<用於儲存Raw圖的Buffer
        int m_nPayloadSize = 0;                   ///<影象資料大小
        int m_nWidth = 0;                   ///<影象寬度
        int m_nHeigh = 0;                   ///<影象高度
        Bitmap m_bitmapForSave = null;                ///<bitmap物件,僅供儲存影象使用
        const uint PIXEL_FORMATE_BIT = 0x00FF0000;          ///<用於與當前的資料格式進行與運算得到當前的資料位數
        const uint GX_PIXEL_8BIT = 0x00080000;          ///<8位資料影象格式
        ///
        const int COLORONCOLOR = 3;
        const uint DIB_RGB_COLORS = 0;
        const uint SRCCOPY = 0x00CC0020;
        CWin32Bitmaps.BITMAPINFO m_objBitmapInfo = new CWin32Bitmaps.BITMAPINFO();
        IntPtr m_pBitmapInfo = IntPtr.Zero;
        Graphics m_objGC = null;
        IntPtr m_pHDC = IntPtr.Zero;


        /// <summary>
        /// 建構函式用於初始化裝置物件與PictureBox控制元件物件
        /// </summary>
        /// <param name="objIGXDevice">裝置物件</param>
        /// <param name="objPictureBox">影象顯示控制元件</param>
        public GxBitmap(IGXDevice objIGXDevice, PictureBox objPictureBox)
        {
            m_objIGXDevice = objIGXDevice;
            m_pic_ShowImage = objPictureBox;
            string strValue = null;
            if (null != objIGXDevice)
            {
                //獲得影象原始資料大小、寬度、高度等
                m_nPayloadSize = (int)objIGXDevice.GetRemoteFeatureControl().GetIntFeature("PayloadSize").GetValue();
                m_nWidth = (int)objIGXDevice.GetRemoteFeatureControl().GetIntFeature("Width").GetValue();
                m_nHeigh = (int)objIGXDevice.GetRemoteFeatureControl().GetIntFeature("Height").GetValue();

                //獲取是否為彩色相機
                if (objIGXDevice.GetRemoteFeatureControl().IsImplemented("PixelColorFilter"))
                {
                    strValue = objIGXDevice.GetRemoteFeatureControl().GetEnumFeature("PixelColorFilter").GetValue();

                    if ("None" != strValue)
                    {
                        m_bIsColor = true;
                    }
                }
            }

            //申請用於快取影象資料的buffer
            m_byRawBuffer = new byte[m_nPayloadSize];
            m_byMonoBuffer = new byte[__GetStride(m_nWidth, m_bIsColor) * m_nHeigh];
            m_byColorBuffer = new byte[__GetStride(m_nWidth, m_bIsColor) * m_nHeigh];

            __CreateBitmap(out m_bitmapForSave, m_nWidth, m_nHeigh, m_bIsColor);

            m_objGC = m_pic_ShowImage.CreateGraphics();
            m_pHDC = m_objGC.GetHdc();
            if (m_bIsColor)
            {
                m_objBitmapInfo.bmiHeader.biSize = (uint)Marshal.SizeOf(typeof(CWin32Bitmaps.BITMAPINFOHEADER));
                m_objBitmapInfo.bmiHeader.biWidth = m_nWidth;
                m_objBitmapInfo.bmiHeader.biHeight = -m_nHeigh;
                m_objBitmapInfo.bmiHeader.biPlanes = 1;
                m_objBitmapInfo.bmiHeader.biBitCount = 24;
                m_objBitmapInfo.bmiHeader.biCompression = 0;
                m_objBitmapInfo.bmiHeader.biSizeImage = 0;
                m_objBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
                m_objBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
                m_objBitmapInfo.bmiHeader.biClrUsed = 0;
                m_objBitmapInfo.bmiHeader.biClrImportant = 0;
            }
            else
            {
                m_objBitmapInfo.bmiHeader.biSize = (uint)Marshal.SizeOf(typeof(CWin32Bitmaps.BITMAPINFOHEADER));
                m_objBitmapInfo.bmiHeader.biWidth = m_nWidth;
                m_objBitmapInfo.bmiHeader.biHeight = -m_nHeigh;
                m_objBitmapInfo.bmiHeader.biPlanes = 1;
                m_objBitmapInfo.bmiHeader.biBitCount = 8;
                m_objBitmapInfo.bmiHeader.biCompression = 0;
                m_objBitmapInfo.bmiHeader.biSizeImage = 0;
                m_objBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
                m_objBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
                m_objBitmapInfo.bmiHeader.biClrUsed = 0;
                m_objBitmapInfo.bmiHeader.biClrImportant = 0;

                m_objBitmapInfo.bmiColors = new CWin32Bitmaps.RGBQUAD[256];
                // 黑白影象需要初始化調色盤
                for (int i = 0; i < 256; i++)
                {
                    m_objBitmapInfo.bmiColors[i].rgbBlue = (byte)i;
                    m_objBitmapInfo.bmiColors[i].rgbGreen = (byte)i;
                    m_objBitmapInfo.bmiColors[i].rgbRed = (byte)i;
                    m_objBitmapInfo.bmiColors[i].rgbReserved = (byte)i;
                }
            }
            m_pBitmapInfo = Marshal.AllocHGlobal(2048);
            Marshal.StructureToPtr(m_objBitmapInfo, m_pBitmapInfo, false);
        }

        /// <summary>
        /// 用於影象處理後並顯示影象
        /// </summary>
        /// <param name="objCfg">影象處理引數配置物件</param>
        /// <param name="objIBaseData">影象資料物件</param>
        public void ShowImageProcess(IImageProcessConfig objCfg, IBaseData objIBaseData)
        {
            //檢查影象是否改變並更新Buffer
            __UpdateBufferSize(objIBaseData);

            if (null != objIBaseData)
            {
                if (GX_FRAME_STATUS_LIST.GX_FRAME_STATUS_SUCCESS == objIBaseData.GetStatus())
                {
                    if (m_bIsColor)
                    {
                        IntPtr pBufferColor = objIBaseData.ImageProcess(objCfg);
                        Marshal.Copy(pBufferColor, m_byColorBuffer, 0, __GetStride(m_nWidth, m_bIsColor) * m_nHeigh);
                        __ShowImage(m_byColorBuffer);
                    }
                    else
                    {
                        IntPtr pBufferMono = objIBaseData.ImageProcess(objCfg);
                        Marshal.Copy(pBufferMono, m_byMonoBuffer, 0, __GetStride(m_nWidth, m_bIsColor) * m_nHeigh);

                        __ShowImage(m_byMonoBuffer);
                    }
                }
            }
        }


        /// <summary>
        /// 用於顯示影象
        /// </summary>
        /// <param name="objIBaseData">影象資料物件</param>
        public void Show(IBaseData objIBaseData)
        {
            GX_VALID_BIT_LIST emValidBits = GX_VALID_BIT_LIST.GX_BIT_0_7;

            //檢查影象是否改變並更新Buffer
            __UpdateBufferSize(objIBaseData);


            if (null != objIBaseData)
            {
                emValidBits = __GetBestValudBit(objIBaseData.GetPixelFormat());
                if (GX_FRAME_STATUS_LIST.GX_FRAME_STATUS_SUCCESS == objIBaseData.GetStatus())
                {
                    if (m_bIsColor)
                    {
                        IntPtr pBufferColor = objIBaseData.ConvertToRGB24(emValidBits, GX_BAYER_CONVERT_TYPE_LIST.GX_RAW2RGB_NEIGHBOUR, false);
                        Marshal.Copy(pBufferColor, m_byColorBuffer, 0, __GetStride(m_nWidth, m_bIsColor) * m_nHeigh);
                        __ShowImage(m_byColorBuffer);
                    }
                    else
                    {
                        IntPtr pBufferMono = IntPtr.Zero;
                        if (__IsPixelFormat8(objIBaseData.GetPixelFormat()))
                        {
                            pBufferMono = objIBaseData.GetBuffer();
                        }
                        else
                        {
                            pBufferMono = objIBaseData.ConvertToRaw8(emValidBits);
                        }
                        Marshal.Copy(pBufferMono, m_byMonoBuffer, 0, __GetStride(m_nWidth, m_bIsColor) * m_nHeigh);

                        __ShowImage(m_byMonoBuffer);
                    }
                }
            }
        }

        /// <summary>
        /// 儲存影象
        /// </summary>
        /// <param name="objIBaseData">影象資料物件</param>
        /// <param name="strFilePath">顯示影象檔名</param>
        public Bitmap SaveBmp(IBaseData objIBaseData)
        {
            GX_VALID_BIT_LIST emValidBits = GX_VALID_BIT_LIST.GX_BIT_0_7;

            //檢查影象是否改變並更新Buffer
            __UpdateBufferSize(objIBaseData);

            if (null != objIBaseData)
            {
                emValidBits = __GetBestValudBit(objIBaseData.GetPixelFormat());
                if (m_bIsColor)
                {
                    IntPtr pBufferColor = objIBaseData.ConvertToRGB24(emValidBits, GX_BAYER_CONVERT_TYPE_LIST.GX_RAW2RGB_NEIGHBOUR, false);
                    Marshal.Copy(pBufferColor, m_byColorBuffer, 0, __GetStride(m_nWidth, m_bIsColor) * m_nHeigh);
                    __UpdateBitmapForSave(m_byColorBuffer);
                }
                else
                {
                    IntPtr pBufferMono = IntPtr.Zero;
                    if (__IsPixelFormat8(objIBaseData.GetPixelFormat()))
                    {
                        pBufferMono = objIBaseData.GetBuffer();
                    }
                    else
                    {
                        pBufferMono = objIBaseData.ConvertToRaw8(emValidBits);
                    }
                    Marshal.Copy(pBufferMono, m_byMonoBuffer, 0, __GetStride(m_nWidth, m_bIsColor) * m_nHeigh);

                    __UpdateBitmapForSave(m_byMonoBuffer);
                }
                return m_bitmapForSave;
            }
            return null;
        }

        /// <summary>
        /// 儲存Raw影象
        /// </summary>
        /// <param name="objIBaseData">影象資料物件</param>
        /// <param name="strFilePath">顯示影象檔名</param>
        public void SaveRaw(IBaseData objIBaseData, string strFilePath)
        {
            Stream objFileStream = new FileStream(strFilePath, FileMode.Create);
            BinaryWriter objSW = new BinaryWriter(objFileStream);

            //檢查影象是否改變並更新Buffer
            __UpdateBufferSize(objIBaseData);

            if (null != objIBaseData)
            {
                IntPtr pBufferRaw = objIBaseData.GetBuffer();
                Marshal.Copy(pBufferRaw, m_byRawBuffer, 0, m_nPayloadSize);
            }

            objSW.Write(m_byRawBuffer);
            objSW.Close();
            objFileStream.Close();
        }

        /// <summary>
        /// 檢查影象是否改變並更新Buffer
        /// </summary>
        /// <param name="objIBaseData">影象資料物件</param>
        private void __UpdateBufferSize(IBaseData objIBaseData)
        {
            if (null != objIBaseData)
            {
                if (__IsCompatible(m_bitmapForSave, m_nWidth, m_nHeigh, m_bIsColor))
                {
                    m_nPayloadSize = (int)objIBaseData.GetPayloadSize();
                    m_nWidth = (int)objIBaseData.GetWidth();
                    m_nHeigh = (int)objIBaseData.GetHeight();
                }
                else
                {
                    m_nPayloadSize = (int)objIBaseData.GetPayloadSize();
                    m_nWidth = (int)objIBaseData.GetWidth();
                    m_nHeigh = (int)objIBaseData.GetHeight();

                    m_byRawBuffer = new byte[m_nPayloadSize];
                    m_byMonoBuffer = new byte[__GetStride(m_nWidth, m_bIsColor) * m_nHeigh];
                    m_byColorBuffer = new byte[__GetStride(m_nWidth, m_bIsColor) * m_nHeigh];

                    //更新BitmapInfo
                    m_objBitmapInfo.bmiHeader.biWidth = m_nWidth;
                    m_objBitmapInfo.bmiHeader.biHeight = m_nHeigh;
                    Marshal.StructureToPtr(m_objBitmapInfo, m_pBitmapInfo, false);
                }
            }
        }

        /// <summary>
        /// 更新儲存資料
        /// </summary>
        /// <param name="byBuffer">影象buffer</param>
        private void __UpdateBitmapForSave(byte[] byBuffer)
        {
            if (__IsCompatible(m_bitmapForSave, m_nWidth, m_nHeigh, m_bIsColor))
            {
                __UpdateBitmap(m_bitmapForSave, byBuffer, m_nWidth, m_nHeigh, m_bIsColor);
            }
            else
            {
                __CreateBitmap(out m_bitmapForSave, m_nWidth, m_nHeigh, m_bIsColor);
                __UpdateBitmap(m_bitmapForSave, byBuffer, m_nWidth, m_nHeigh, m_bIsColor);
            }
        }

        /// <summary>
        /// 顯示影象處理
        /// </summary>
        /// <param name="byBuffer">影象資料buffer</param>
        private void __ShowImage(byte[] byBuffer)
        {
            if (null != m_pic_ShowImage)
            {
                CWin32Bitmaps.SetStretchBltMode(m_pHDC, COLORONCOLOR);
                CWin32Bitmaps.StretchDIBits(
                            m_pHDC,
                            0,
                            0,
                            m_pic_ShowImage.Width,
                            m_pic_ShowImage.Height,
                            0,
                            0,
                            m_nWidth,
                            m_nHeigh,
                            byBuffer,
                            m_pBitmapInfo,
                            DIB_RGB_COLORS,
                            SRCCOPY);
            }
        }

        /// <summary>
        /// 判斷PixelFormat是否為8位
        /// </summary>
        /// <param name="emPixelFormatEntry">影象資料格式</param>
        /// <returns>true為8為資料,false為非8位資料</returns>
        private bool __IsPixelFormat8(GX_PIXEL_FORMAT_ENTRY emPixelFormatEntry)
        {
            bool bIsPixelFormat8 = false;
            uint uiPixelFormatEntry = (uint)emPixelFormatEntry;
            if ((uiPixelFormatEntry & PIXEL_FORMATE_BIT) == GX_PIXEL_8BIT)
            {
                bIsPixelFormat8 = true;
            }
            return bIsPixelFormat8;
        }

        /// <summary>
        /// 通過GX_PIXEL_FORMAT_ENTRY獲取最優Bit位
        /// </summary>
        /// <param name="em">影象資料格式</param>
        /// <returns>最優Bit位</returns>
        private GX_VALID_BIT_LIST __GetBestValudBit(GX_PIXEL_FORMAT_ENTRY emPixelFormatEntry)
        {
            GX_VALID_BIT_LIST emValidBits = GX_VALID_BIT_LIST.GX_BIT_0_7;
            switch (emPixelFormatEntry)
            {
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO8:
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GR8:
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_RG8:
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GB8:
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_BG8:
                    {
                        emValidBits = GX_VALID_BIT_LIST.GX_BIT_0_7;
                        break;
                    }
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO10:
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GR10:
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_RG10:
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GB10:
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_BG10:
                    {
                        emValidBits = GX_VALID_BIT_LIST.GX_BIT_2_9;
                        break;
                    }
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO12:
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GR12:
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_RG12:
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GB12:
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_BG12:
                    {
                        emValidBits = GX_VALID_BIT_LIST.GX_BIT_4_11;
                        break;
                    }
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO14:
                    {
                        //暫時沒有這樣的資料格式待升級
                        break;
                    }
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO16:
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GR16:
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_RG16:
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GB16:
                case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_BG16:
                    {
                        //暫時沒有這樣的資料格式待升級
                        break;
                    }
                default:
                    break;
            }
            return emValidBits;
        }

        /// <summary>
        /// 獲取影象顯示格式
        /// </summary>
        /// <param name="bIsColor">是否為彩色相機</param>
        /// <returns>影象的資料格式</returns>
        private PixelFormat __GetFormat(bool bIsColor)
        {
            return bIsColor ? PixelFormat.Format24bppRgb : PixelFormat.Format8bppIndexed;
        }

        /// <summary>
        /// 計算寬度所佔的位元組數
        /// </summary>
        /// <param name="nWidth">影象寬度</param>
        /// <param name="bIsColor">是否是彩色相機</param>
        /// <returns>影象一行所佔的位元組數</returns>
        private int __GetStride(int nWidth, bool bIsColor)
        {
            return bIsColor ? nWidth * 3 : nWidth;
        }

        /// <summary>
        /// 判斷是否相容
        /// </summary>
        /// <param name="bitmap">Bitmap物件</param>
        /// <param name="nWidth">影象寬度</param>
        /// <param name="nHeight">影象高度</param>
        /// <param name="bIsColor">是否是彩色相機</param>
        /// <returns>true為一樣,false不一樣</returns>
        private bool __IsCompatible(Bitmap bitmap, int nWidth, int nHeight, bool bIsColor)
        {
            if (bitmap == null
                || bitmap.Height != nHeight
                || bitmap.Width != nWidth
                || bitmap.PixelFormat != __GetFormat(bIsColor)
             )
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 建立Bitmap
        /// </summary>
        /// <param name="bitmap">Bitmap物件</param>
        /// <param name="nWidth">影象寬度</param>
        /// <param name="nHeight">影象高度</param>
        /// <param name="bIsColor">是否是彩色相機</param>
        private void __CreateBitmap(out Bitmap bitmap, int nWidth, int nHeight, bool bIsColor)
        {
            bitmap = new Bitmap(nWidth, nHeight, __GetFormat(bIsColor));
            if (bitmap.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                ColorPalette colorPalette = bitmap.Palette;
                for (int i = 0; i < 256; i++)
                {
                    colorPalette.Entries[i] = Color.FromArgb(i, i, i);
                }
                bitmap.Palette = colorPalette;
            }
        }

        /// <summary>
        /// 更新和複製影象資料到Bitmap的buffer
        /// </summary>
        /// <param name="bitmap">Bitmap物件</param>
        /// <param name="nWidth">影象寬度</param>
        /// <param name="nHeight">影象高度</param>
        /// <param name="bIsColor">是否是彩色相機</param>
        private void __UpdateBitmap(Bitmap bitmap, byte[] byBuffer, int nWidth, int nHeight, bool bIsColor)
        {
            //給BitmapData加鎖
            BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
            
            //得到一個指向Bitmap的buffer指標
            IntPtr ptrBmp = bmpData.Scan0;
            int nImageStride = __GetStride(m_nWidth, bIsColor);
            //影象寬能夠被4整除直接copy
            if (nImageStride == bmpData.Stride)
            {
                Marshal.Copy(byBuffer, 0, ptrBmp, bmpData.Stride * bitmap.Height);
            }
            else//影象寬不能夠被4整除按照行copy
            {
                for (int i = 0; i < bitmap.Height; ++i)
                {
                    Marshal.Copy(byBuffer, i * nImageStride, new IntPtr(ptrBmp.ToInt64() + i * bmpData.Stride), m_nWidth);
                }
            }
            //BitmapData解鎖
            bitmap.UnlockBits(bmpData);
        }
    }
}

其中建構函式中,形參接受pictureBox的輸入

然後得到pictureBox的控制代碼,如何得到呢

m_objGC = objPictureBox.CreateGraphics();
m_pHDC = m_objGC.GetHdc();

隨後將控制代碼與影象屬性和影象資料穿給系統中C編寫的dll,gdi32.dll

  private void __ShowImage(byte[] byBuffer)
        {
            if (null != m_pic_ShowImage)
            {
                CWin32Bitmaps.SetStretchBltMode(m_pHDC, COLORONCOLOR);
                CWin32Bitmaps.StretchDIBits(
                            m_pHDC,
                            0,
                            0,
                            m_pic_ShowImage.Width,
                            m_pic_ShowImage.Height,
                            0,
                            0,
                            m_nWidth,
                            m_nHeigh,
                            byBuffer,
                            m_pBitmapInfo,
                            DIB_RGB_COLORS,
                            SRCCOPY);
            }
        }
        [DllImport("gdi32.dll", CharSet = CharSet.Auto)]
        public static extern int StretchDIBits(
            HDC hdc,                   // handle to DC
            int XDest,                 // x-coord of destination upper-left corner
            int YDest,                 // y-coord of destination upper-left corner
            int nDestWidth,            // width of destination rectangle
            int nDestHeight,           // height of destination rectangle
            int XSrc,                  // x-coord of source upper-left corner
            int YSrc,                  // y-coord of source upper-left corner
            int nSrcWidth,             // width of source rectangle
            int nSrcHeight,            // height of source rectangle
            byte[] lpBits,             // bitmap bits
            LPVOID lpBitsInfo,         // bitmap data            
            UINT iUsage,               // usage options
            DWORD dwRop                // raster operation code
            );

記得這個系統函式因為是C編寫的dll , 所以要DLLImport引入,會固定更新hdc控制代碼上的影象。

關於StrtchDIBits函式的說明

StretchDIBits 函式把DIB、JPEG、PNG影象中一矩形區域內的畫素顏色資料複製到指定的目標矩形裡。如果目標矩形大於源矩形,此函式將拉伸的行和列以適合目標矩形的顏色資料。如果目標矩形小於源矩形,則此函式使用指定的光柵操作壓縮的行和列。(Note:整幅影象都會被顯示在一個矩形區域中,這個矩形區域不許顯示原圖全貌)

語法:

int StretchDIBits (HDC hdc,int XDest,YDest,int int nDestWidth,int nDestHeight,int XSrc,int YSrc,int nSrcWidth,int nSrcHeight,const VOID __in * lpBits,__in const BITMAPINFO * lpBitsInfo,__in UINT iUsage,__in dword = dwRop) ;

引數:

hdc [in](Note:不知道這[in]代表什麼暫且認為它並不重要吧)

目標裝置上下文的控制代碼。

XDest [in]

角點的 x 座標,以邏輯單位的目標矩形的左上角。

YDest [in]

Y 座標,邏輯單位上的目標矩形的左上角。

nDestWidth [in]

邏輯單位,目標矩形的寬度。

nDestHeight [in]

邏輯單位,目標矩形的高度。

XSrc [in]

角的 x 座標,以畫素為單位,源矩形影象中。

YSrc [in]

Y 座標,以畫素為單位,源矩形影象中。

nSrcWidth [in]

寬度,以畫素為單位,源矩形影象中。

nSrcHeight [in]

高度以畫素為單位,源矩形影象中。

lpBits [in]

影象的位,作為位元組陣列儲存的指標。有關詳細資訊,請參見備註部分。

lpBitsInfo [in]

指向包含DIB 相關資訊的 BITMAPINFO 結構的指標。

iUsage [in]

指定是否提供的 BITMAPINFO 結構的 bmiColors 成員,以及若然,是否 bmiColors 包含顯式的紅、 綠、 藍 (RGB) 值或索引。IUsage 引數必須是下列值之一。

備註

DIB_RGB_COLORS

顏色表中包含文字的 RGB 值。

DIB_PAL_COLORS

該陣列包含到源裝置上下文的邏輯調色盤的 16 位索引。

dwRop [in]

指定的方式組合在一起以形成新的影象源畫素、 目標裝置上下文的當前畫刷和目標畫素。有關詳細資訊,請參閱下面的備註部分。

返回值

如果函式成功,則返回值是掃描複製的行數。請注意,此值可以為負的映象內容。

如果該函式失敗,或者沒有掃描行被複制,則返回值為 0。

如果驅動程式不支援 JPEG 或 PNG 檔案影象傳遞給 StretchDIBits,該函式將失敗並返回 GDI_ERROR。如果發生故障,應用程式必須依靠自己的 JPEG 或 PNG 支援,將影象的解壓縮成點陣圖,然後將該點陣圖傳遞給 StretchDIBits。

DIB裝置無關點陣圖檔案

這是一種檔案格式,是為了保證由某個應用程式建立的點陣圖圖形可以被其它應用程式裝載或顯示。 DIB的與裝置無關性主要體現在以下兩個方面:DIB的顏色模式與裝置無關。例如,一個256色的DIB即可以在真彩色顯示模式下使用,也可以在16色模式下使用。256色以下(包括256色)的DIB擁有自己的顏色表,畫素的顏色獨立於系統調色盤。由於DIB不依賴於具體裝置,因此可以用來永久性地儲存圖象。DIB一般是以*.BMP檔案的形式儲存在磁碟中的,有時也會儲存在*.DIB檔案中。執行在不同輸出裝置下的應用程式可以通過DIB來交換圖象。