none
Image控件显示和CPU占用的问题 RRS feed

  • 问题

  • 一个线程中的while(25帧)不停的获取图片数据,600万像素的BGR24数据,收到一帧数据后后触发一个事件,往一个WriteableBitmap中写这些像素数据,写完一张后,Image.Source = WriteableBitmap。在运行期间发现CPU占用率达到%50左右(Atom E3845),是否正常?是否有好的方法减少CPU的开支。

    2017年9月14日 8:04

答案


  • Hi Xin H,

    >>注释掉 给Image控件的Source属性赋值 的语句Image.Source = WriteableBitmap,CPU的占用就降低下来了,是否是赋值这个语句的开销太大

    你使用WriteableBitmap方法来计算600万像素的BGR24数据,并生成Bitmap对象,然后在WPF image控件上显示。本身耗费CPU的地方是WriteableBitmap方法。 不是把image源赋给image控件消耗CPU资源。

    比如下面的这个WriteableBitmap方法:

             int width = 188;
                int height = 188;
                var format = System.Drawing.Imaging.PixelFormat.Format32bppArgb;
                var lockMode = System.Drawing.Imaging.ImageLockMode.WriteOnly;
                var bitmap = new Bitmap(width, height, format);
                var bitmapRect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
                System.Drawing.Imaging.BitmapData bmpData = bitmap.LockBits(bitmapRect, lockMode, format);
                {
                    int length = Math.Abs(bmpData.Stride) * bitmap.Height;
                    byte[] bitmapBytes = new byte[length];
                    int index = 0;
                    for (int j = height - 1; j >= 0; j--)
                    {
                        for (int i = 0; i < width; i++)
                        {
                            //pdata一维数组
                            Pixel v = pdata[index++];
                            bitmapBytes[j * bmpData.Stride + i * 4 + 0] = v.b;
                            bitmapBytes[j * bmpData.Stride + i * 4 + 1] = v.g;
                            bitmapBytes[j * bmpData.Stride + i * 4 + 2] = v.r;
                            bitmapBytes[j * bmpData.Stride + i * 4 + 3] = v.a;
                        }
                    }
    
                    System.Runtime.InteropServices.Marshal.Copy(bitmapBytes, 0, bmpData.Scan0, length);
                }
                bitmap.UnlockBits(bmpData);
                // bitmap.Save("filename");
    
                // 赋值的语句占用不了多少CPU资源。
                imagename.Source = BitmapToImageSource(bitmap);
    
    BitmapImage BitmapToImageSource(Bitmap bitmap)
    {
        using (MemoryStream memory = new MemoryStream())
        {
            bitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Bmp);
            memory.Position = 0;
            BitmapImage bitmapimage = new BitmapImage();
            bitmapimage.BeginInit();
            bitmapimage.StreamSource = memory;
            bitmapimage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapimage.EndInit();
    
            return bitmapimage;
        }
    }


    >>,是否正常?是否有好的方法减少CPU的开支。

    正常。目前没有好的方法,如果操作频繁,我建议换更好性能的电脑,或者可以找一些三方的控件或者图片库来处理。他们可能会有更优异的计算方法。

    Best Regards,

    Yohann Lu



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 Xin H 2017年9月15日 7:53
    2017年9月15日 6:46
    版主

全部回复

  • 如果只有单一线程且不停的运作,以一张600万像素来说,

    的确有可能会让CPU忙录(如果不作其他处理的逻辑下)。

    可是是否会达到50%,这可能还要分析原因。




    2017年9月14日 8:23
  • 我注释掉 给Image控件的Source属性赋值 的语句Image.Source = WriteableBitmap,CPU的占用就降低下来了,是否是赋值这个语句的开销太大
    2017年9月14日 8:36

  • Hi Xin H,

    >>注释掉 给Image控件的Source属性赋值 的语句Image.Source = WriteableBitmap,CPU的占用就降低下来了,是否是赋值这个语句的开销太大

    你使用WriteableBitmap方法来计算600万像素的BGR24数据,并生成Bitmap对象,然后在WPF image控件上显示。本身耗费CPU的地方是WriteableBitmap方法。 不是把image源赋给image控件消耗CPU资源。

    比如下面的这个WriteableBitmap方法:

             int width = 188;
                int height = 188;
                var format = System.Drawing.Imaging.PixelFormat.Format32bppArgb;
                var lockMode = System.Drawing.Imaging.ImageLockMode.WriteOnly;
                var bitmap = new Bitmap(width, height, format);
                var bitmapRect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
                System.Drawing.Imaging.BitmapData bmpData = bitmap.LockBits(bitmapRect, lockMode, format);
                {
                    int length = Math.Abs(bmpData.Stride) * bitmap.Height;
                    byte[] bitmapBytes = new byte[length];
                    int index = 0;
                    for (int j = height - 1; j >= 0; j--)
                    {
                        for (int i = 0; i < width; i++)
                        {
                            //pdata一维数组
                            Pixel v = pdata[index++];
                            bitmapBytes[j * bmpData.Stride + i * 4 + 0] = v.b;
                            bitmapBytes[j * bmpData.Stride + i * 4 + 1] = v.g;
                            bitmapBytes[j * bmpData.Stride + i * 4 + 2] = v.r;
                            bitmapBytes[j * bmpData.Stride + i * 4 + 3] = v.a;
                        }
                    }
    
                    System.Runtime.InteropServices.Marshal.Copy(bitmapBytes, 0, bmpData.Scan0, length);
                }
                bitmap.UnlockBits(bmpData);
                // bitmap.Save("filename");
    
                // 赋值的语句占用不了多少CPU资源。
                imagename.Source = BitmapToImageSource(bitmap);
    
    BitmapImage BitmapToImageSource(Bitmap bitmap)
    {
        using (MemoryStream memory = new MemoryStream())
        {
            bitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Bmp);
            memory.Position = 0;
            BitmapImage bitmapimage = new BitmapImage();
            bitmapimage.BeginInit();
            bitmapimage.StreamSource = memory;
            bitmapimage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapimage.EndInit();
    
            return bitmapimage;
        }
    }


    >>,是否正常?是否有好的方法减少CPU的开支。

    正常。目前没有好的方法,如果操作频繁,我建议换更好性能的电脑,或者可以找一些三方的控件或者图片库来处理。他们可能会有更优异的计算方法。

    Best Regards,

    Yohann Lu



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 Xin H 2017年9月15日 7:53
    2017年9月15日 6:46
    版主