如何设置RenderTarget2D.SaveAsJpeg()的质量?

时间:2011-02-10 08:13:02

标签: c# windows-phone-7 xna-4.0

public void SaveAsJpeg(Stream stream, int width, int height)

RenderTarget2D.SaveAsJpeg()缺少一个参数来设置Jpeg质量,输出有很多工件。 (增加图像的大小确实有点帮助,但看起来仍然很糟糕)

该参数是否隐藏在XNA中的某个位置?如何提高jpeg的质量?

2 个答案:

答案 0 :(得分:2)

XNA 4.0 API中没有用于编码JPEG图像的质量参数。

作为一种非常全面的处理方式,您可以创建Silverlight WriteableBitmap,将数据从渲染目标中复制到其中,然后使用Extensions.SaveJpeg来保存它具有自定义的质量水平。

更好的选择可能是简单地保存PNG图像。

答案 1 :(得分:0)

我同意Andrew Russel的说法,一个更好的选择就是简单地保存到PNG,但如果你只是要保存到jpg,那么有一个比写GoableBitmap更好的方法。

你可以做的是创建一个空的Bitmap对象并传输纹理数据,这样你就可以进行Texture2D到Bitmap的转换。只需从下面复制:

    public static Bitmap ToBitmap(this Microsoft.Xna.Framework.Graphics.Texture2D rd, int Width, int Height)
    {
        var Bmp = new Bitmap(Width, Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

        byte[] data = ToBytes(rd);

        var bmpData = Bmp.LockBits(new Rectangle(0, 0, rd.Width, rd.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

        System.Runtime.InteropServices.Marshal.Copy(data, 0, bmpData.Scan0, data.Length);

        Bmp.UnlockBits(bmpData);

        return Bmp;
    }

    public static byte[] ToBytes(this Microsoft.Xna.Framework.Graphics.Texture2D rd)
    {
        byte[] data = new byte[4 * rd.Height * rd.Width];
        rd.GetData<byte>(data);

        SwapBytes(data);

        return data;
    }

    private static void SwapBytes(byte[] data)
    {
        System.Threading.Tasks.ParallelOptions po = new System.Threading.Tasks.ParallelOptions();
        po.MaxDegreeOfParallelism = -1;

        System.Threading.Tasks.Parallel.For(0, data.Length / 4, po, t =>
        {
            int bi = t * 4;
            byte temp = data[bi];
            data[bi] = data[bi + 2];
            data[bi + 2] = temp;
        });
    }

请注意,上述内容非常有效,但有一些缺点。与上面类似的代码可以用来非常快速地实现Bitmap到Texture2D的转换,但是没有预乘alpha。