2013/9/7

[C#] 動態產生文字圖片(Generated Image dynamic text)& 圖片疊加(Image Overlap)

在之前的例子中使用 WebCam QRCode Reader
在成功擷取圖片之後,會把圖片擷取下來
想說如果存下來的照片能有解碼的結果會更好



這邊需要兩個功能
一個是要能動態產生文字圖片 (Generated Image dynamic text)
一個是將兩張圖片做疊合 (Image Overlap)

有關對圖片做編輯或是其他相關的設定都是使用
Graphics 這個類別
要動態產生文字圖片其實很簡單
首先先準備一張底圖 (Background.png)

其實也可以依據各人喜歡在底圖上做些變化

        /// <summary>
        /// 動態在背景上Key上文字
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private Image GenerateFontMark(string str)
        {        
            //取得背景的底圖
            string path = _phtoDirectory + "Background.png";
            //讀取圖片
            System.Drawing.Image imgSrc = System.Drawing.Image.FromFile(path);

            using (Graphics g = Graphics.FromImage(imgSrc))
            {
                g.DrawImage(imgSrc, 0, 0, imgSrc.Width, imgSrc.Height);
                //文字要使用的字體及文字大小
                using (Font f = new Font("宋體", 13))
                {
                    using (Brush b = new SolidBrush(Color.Yellow))
                    {
                        //在圖片上加上文字
                        //(要加入的文字,字體,X軸位置,Y軸位置)
                        g.DrawString(str, f, b, 5, 5);
                    }
                }
            }

            return imgSrc;
        }

呼叫上面的Function就可以動態的產生文字圖片了

先來講對圖片縮放的小技巧
原本以為會很難,其實只要一行就可以改變圖片的大小
這邊縮小圖片是為了讓產生的圖片有邊框的效果

                //縮小照片尺寸
                //(要縮小的照片,寬度(Width),高度(Height))
                Image newPic = new Bitmap(frame.ToBitmap(), 630, 440);

做好底圖之後接著就是把拍下的結果疊在一起了

        private void GenerateWaterMark(Image tempPic, string result)
        {
            //在背景圖片中加上文字
            System.Drawing.Image imgSrc = GenerateFontMark(result);
            //要疊在上層的圖片
            System.Drawing.Image imgWarter = tempPic;

            //進行圖片的疊加 
            using (Graphics g = Graphics.FromImage(imgSrc))
            {
                //要疊的是哪張圖片
                g.DrawImage(imgWarter, 
                    //上層圖片從底圖的哪個位置開始疊(X,Y)
                    new Rectangle(5,35,imgWarter.Width,imgWarter.Height),
                    0, 0, imgWarter.Width, imgWarter.Height, GraphicsUnit.Pixel);
            }

            imgSrc.Save(_fileName);
        
        }

結果就是這樣


當然也可以用在之前產生 QRCode Generator
在產生QRCode時,把想要顯示的訊息一併列出來


DEMO

2013/9/4

[C#] WebCam QRCode Reader

之前的文章寫到使用WebCam錄影拍照  和 QRCode Reader
有這兩個基礎的功能,我們很容易就可以把WebCam 變成 QRCode Reader


一開始先做畫面
先拉一個button,label,pictureBox
在button的處裡事件裡面寫
開啟攝影機和Timer
這是WebCam錄影拍照  的一些方法
        private void button1_Click(object sender, EventArgs e)
        {
            openWebCam();
            _timer.Start();
        }

觸發Tiemr之後就每0.1秒擷取畫面一次
將畫面顯示在 pictureBox 中
並且將擷取的畫面丟給QRCode Reader去解碼
當成功讀到QRCode時,將當時的影像儲存下來
        private void TimerEventProcessor(object sender, EventArgs e)
        {
            Image<Bgr, Byte> frame = cap.QueryFrame(); // Query 攝影機的畫面

            pictureBox1.Image = frame.ToBitmap(); // 把畫面轉換成bitmap型態,在丟給pictureBox元件

            //宣告 QRCode Reader 物件
            ZXing.IBarcodeReader reader = new ZXing.BarcodeReader();
            // bitmap = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromFile(@"D:\Test\QRCode\temp.png");

            //將攝影影擷取的畫面直接丟進Reader 進行解碼
            ZXing.Result result = reader.Decode(frame.ToBitmap());

            if (result != null)
            {   //如果有成功解讀,則顯示文字

                //在Thread裡面不能直接跟控制項(Text)互動,所以使用委派(Delegate)的方式
                this.Invoke(new InvokeFunction(this.TrueFunction), new object[] { result.Text });

                //將解讀成功的影像存下來
                //儲存路徑
                _fileName = string.Format("{0}{1}{2}", _phtoDirectory, DateTime.Now.ToString("yyyyMMddHmmss"), ".PNG");

                //儲存影像
                frame.Save(_fileName);
            }
        }

當成功讀到QRCode的同時也顯示在畫面上
這邊就要使用委派(Delegate)的方式

        private delegate void InvokeFunction(string msg); 

        private void TrueFunction(string msg)
        {
            //顯示QRCode訊息
            this.label1.Text = msg;
        } 

之後到 D:\Test\QRCode
就可以發現成功讀取時的影像了

討論:
我使用的攝影機是只有500萬畫素沒有自動對焦的WebCam
一開始在測試時都讀不到QRCode,後來慢慢測試各種距離才發現
只有大概在距離60公分左右才讀的到...

當然每一款攝影機的焦距都不一樣,所以就要多試幾次吧
但是如果有自動對焦的WebCam效果應該很好吧

DEMO