多个旋转图像的性能优化

时间:2014-05-21 13:07:39

标签: c# winforms visual-studio

我正在研究C#窗体中的一个项目,我正在使用图片框来显示多个转速计。

每个图片框由背景图像和图像组成。背景图像是静态的,但图像(显示实际指示符)每秒旋转和更新几次。

背景图片:http://i.stack.imgur.com/FBsKI.jpg

Fron image:http://i.stack.imgur.com/T0nJU.jpg

只要我同时运行一个或两个转速计,它就可以正常工作,但是当我添加更多时,它开始滞后很多。

以下是我用于更新图片框的代码:

private void timer4_Tick(object sender, EventArgs e)
    {
        Bitmap image = RotateImage(indicatorImg, i++, false, true, Color.Transparent);
        pictureBox4.Image = image;
    }

我正在使用的RotateImage函数(感谢RenniePet https://stackoverflow.com/a/16027561/3660713):

public static Bitmap RotateImage(Image inputImage, float angleDegrees, bool upsizeOk,
                                     bool clipOk, Color backgroundColor)
    {
        lock (lockObject)
        {
            // Test for zero rotation and return a clone of the input image
            if (angleDegrees == 0f)
                return (Bitmap)inputImage.Clone();

            // Set up old and new image dimensions, assuming upsizing not wanted and clipping OK
            int oldWidth = inputImage.Width;
            int oldHeight = inputImage.Height;
            int newWidth = oldWidth;
            int newHeight = oldHeight;
            float scaleFactor = 1f;

            // If upsizing wanted or clipping not OK calculate the size of the resulting bitmap
            if (upsizeOk || !clipOk)
            {
                double angleRadians = angleDegrees * Math.PI / 180d;

                double cos = Math.Abs(Math.Cos(angleRadians));
                double sin = Math.Abs(Math.Sin(angleRadians));
                newWidth = (int)Math.Round(oldWidth * cos + oldHeight * sin);
                newHeight = (int)Math.Round(oldWidth * sin + oldHeight * cos);
            }

            // If upsizing not wanted and clipping not OK need a scaling factor
            if (!upsizeOk && !clipOk)
            {
                scaleFactor = Math.Min((float)oldWidth / newWidth, (float)oldHeight / newHeight);
                newWidth = oldWidth;
                newHeight = oldHeight;
            }

            // Create the new bitmap object. If background color is transparent it must be 32-bit, 
            //  otherwise 24-bit is good enough.
            Bitmap newBitmap = new Bitmap(newWidth, newHeight, backgroundColor == Color.Transparent ?
                                             PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb);
            newBitmap.SetResolution(inputImage.HorizontalResolution, inputImage.VerticalResolution);

            // Create the Graphics object that does the work
            using (Graphics graphicsObject = Graphics.FromImage(newBitmap))
            {
                graphicsObject.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                graphicsObject.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                graphicsObject.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

                // Fill in the specified background color if necessary
                if (backgroundColor != Color.Transparent)
                    graphicsObject.Clear(backgroundColor);

                // Set up the built-in transformation matrix to do the rotation and maybe scaling
                graphicsObject.TranslateTransform(newWidth / 2f, newHeight / 2f);

                if (scaleFactor != 1f)
                    graphicsObject.ScaleTransform(scaleFactor, scaleFactor);

                graphicsObject.RotateTransform(angleDegrees);
                graphicsObject.TranslateTransform(-oldWidth / 2f, -oldHeight / 2f);

                // Draw the result 
                graphicsObject.DrawImage(inputImage, 0, 0);
            }

            return newBitmap;
        }
    }

有关如何提高性能的任何想法?有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

我会为启动时所需的每个度数角度创建静态图像列表。

然后,您可以在列表中引用正确的索引并使用该预先旋转的图像。

答案 1 :(得分:0)

感谢您的帮助!

我所做的是我在Winforms项目中添加了WPF控件。 WPF控件包含两个图像,只包含用于旋转前图像的代码:

C#:

    public void Rotate(float deg)
    {
        RotateTransform rt = new RotateTransform(deg);

        image2.RenderTransform = rt;
    }

XAML:

<UserControl x:Class="Project.WPF_imgControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <Image HorizontalAlignment="Left" Name="image1" Stretch="Fill" VerticalAlignment="Top"  Source="/Project;component/Images/Tachometer.png" />
    <Image RenderTransformOrigin =".5,.5" HorizontalAlignment="Left" Name="image2" Stretch="Fill" VerticalAlignment="Top" Source="/Project;component/Images/Pointer_80%25.png" />
</Grid>

现在我只需要找出与标准格式相比,WPF组件中图像看起来呈锯齿状的原因。

编辑:RenderOptions.BitmapScalingMode =&#34; HighQuality&#34;做了诀窍:))

// Jocke