none
Graphics DrawImage 矩形區塊移動方向的前後兩端繪圖有延遲 RRS feed

  • 問題

  • Dear All~

    我想要做出Panel左右方向移入移出的動畫效果
    這個Form具有背景圖片、Panel是半透明的

    以下的測試除了Form是控制項以外,其他都是我自行繪圖,沒有使用實際的控制項

    我使用一個Bitmap作為草稿,在上面繪圖完異動後,最後再讓Form以此草稿來繪製輸出
    異動的範圍九成不會有閃動

    問題在於矩形區塊移動方向的前後兩端會有描繪延遲的現象
    若區塊的水平位移量是10,則水平方向的前後兩端寬度10的範圍會有延遲

    這個延遲類似先填滿上方部分、再填滿中間、又再填滿下方,分次填滿

    我的順序是:
    1. X座標異動
    2. 在草稿繪製(部分)的背景圖
    3. 在草稿繪製半透明區塊 (達到Transparent效果)
    4. Form把草稿繪製在對應的位置
    (重複步驟1)

    請問是否有其他解法可以處理這延遲的問題?

    或是有推薦其他c#語系的開發工具? (正在嘗試WPF)

    private void Form1_Shown(object sender, EventArgs e)
    {
        string ImagePath = @"D:\背景圖片.jpg";
        Bitmap bmpBackground = new Bitmap(Bitmap.FromFile(ImagePath), this.ClientSize.Width, this.ClientSize.Height); //背景圖
    
        Bitmap bmpTemp = new Bitmap(bmpBackground);
        Graphics gpcTemp = Graphics.FromImage(bmpTemp); //草稿
    
        RectangleF RectPanel = new RectangleF(50, 60, 600, 650); //模擬Panel,高度越高、延遲越明顯
        Color ColorPanel = Color.FromArgb(128, 204, 204, 204); //透明色
        SolidBrush BrushPanel = new SolidBrush(ColorPanel); //筆刷
        float OffsetX  = 10; //位移量
    
        Graphics gpcForm = this.CreateGraphics(); //Form
    
        int MoveCnt = 0;
        while(true)
        {
            //先把原本區塊的位置復原 (複製背景圖片覆蓋)
            gpcTemp.DrawImage(bmpBackground, RectPanel, RectPanel, GraphicsUnit.Pixel);
    
            RectPanel.X = RectPanel.X + OffsetX; //區塊位移
            
            //觀察用,每位移十次換方向
            MoveCnt++;
            if (MoveCnt > 10)
            {
                MoveCnt = 0;
                OffsetX = OffsetX * -1;
            }
    
            //區塊繪製 (新的位置)
            gpcTemp.FillRectangle(BrushPanel, RectPanel);
    
            //Form繪製結果
            gpcForm.DrawImage(bmpTemp, 0, 0); //複製全部
            
            Thread.Sleep(100); //暫停久一點,觀察
        }
    }


    • 已編輯 DSMo 2018年10月2日 上午 02:39 補充
    2018年10月1日 上午 08:15

解答

  • 我找到一個不是從Graphics類別解決的方法

    user32.dll 的 AnimateWindow

    它可以傳入Panel的Handle,就可以對Panel執行動畫效果

    參考網址
    http://facileaapprendre.blogspot.com/2012/10/sometime-you-need-add-some-moving.html


    我還是不知道該如何靠自己達成順暢的繪圖?
    DrawImage處理靜態的畫面,很夠用、不會閃動
    但是處理移動的畫面,雖然不會到閃動,但仍舊會有延遲
    除非水平偏移量設為1,但是移動的速度就無法達到期望

    • 已編輯 DSMo 2018年10月2日 上午 09:28
    • 已標示為解答 DSMo 2018年10月3日 上午 12:37
    2018年10月2日 上午 07:47

所有回覆

  • 先 SuspendLayout , 動作完成在 ResumeLayout
    參考過去相關的內容:
    https://social.msdn.microsoft.com/Search/zh-TW/?Refinement=112&query=SuspendLayout

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。 https://skilltree.my/

    2018年10月1日 上午 11:44
    版主
  • [VBNET] 快速呈現縮放選擇框

    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    2018年10月1日 下午 02:46
  • 看看這篇討論有沒有幫助:

    Panel OnPaint lag

    2018年10月2日 上午 12:31
  • Bill Chung 您好~

    this.SuspendLayout();
    graphicForm.DrawImage(bitmapTemp, 0, 0);
    this.ResumeLayout();

    我以上述範例測試這個方法,移動方向兩端的延遲沒有改善
    若X偏移量為10,則矩形區塊前後兩端端寬度10的範圍內才會有此延遲現象



    • 已編輯 DSMo 2018年10月2日 上午 02:17 修改名詞
    2018年10月2日 上午 01:00
  • tihs 您好~

    早先我是用控制項Panel測試,必須撰寫DoubleBuffer才能解決閃動,但是位移範圍的小延遲仍舊無解。

    本次測試除了Form以外,全部的畫面我都是自己繪圖的,降低其他控制項的干擾

    2018年10月2日 上午 01:19
  • 心冷熱情熄 您好~

    我比較不熟VB,從文中看起來的建議應該是 SuspendLayout() 方法吧
    這方法我有試過,如上述範例,只是不曉得用法是否正確

    2018年10月2日 上午 01:25
  • 我找到一個不是從Graphics類別解決的方法

    user32.dll 的 AnimateWindow

    它可以傳入Panel的Handle,就可以對Panel執行動畫效果

    參考網址
    http://facileaapprendre.blogspot.com/2012/10/sometime-you-need-add-some-moving.html


    我還是不知道該如何靠自己達成順暢的繪圖?
    DrawImage處理靜態的畫面,很夠用、不會閃動
    但是處理移動的畫面,雖然不會到閃動,但仍舊會有延遲
    除非水平偏移量設為1,但是移動的速度就無法達到期望

    • 已編輯 DSMo 2018年10月2日 上午 09:28
    • 已標示為解答 DSMo 2018年10月3日 上午 12:37
    2018年10月2日 上午 07:47
  • 如果要做的比較有趣一點的桌面應用程式, WPF 會比較好做。

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。 https://skilltree.my/

    2018年10月3日 下午 03:41
    版主