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

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

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

4

2 回答 2

2

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

作为一种非常迂回的做事方式,您可以创建一个 Silverlight WriteableBitmap,将数据从渲染目标复制到其中,然后使用Extensions.SaveJpeg自定义质量级别保存它。

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

于 2011-02-10T08:33:20.170 回答
0

我同意 Andrew Russel 的观点,一个更好的选择是简单地保存到 PNG,但如果你只是必须保存到 jpg,那么有比通过 WriteableBitmap 更好的方法。

您可以做的是创建一个空的 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;
        });
    }

请注意,上述方法非常有效,但有一些缺点。与上述类似的代码可用于非常快速地实现位图到 Texture2D 的转换,但无需预乘 alpha。

于 2011-06-07T09:02:47.210 回答