public void SaveAsJpeg(Stream stream, int width, int height)
RenderTarget2D.SaveAsJpeg() 缺少用于设置 Jpeg 质量的参数,并且输出有很多工件。(增加图像的大小确实有一点帮助,但看起来仍然很糟糕)
该参数是否隐藏在 XNA 中的某处?如何提高 jpeg 的质量?
public void SaveAsJpeg(Stream stream, int width, int height)
RenderTarget2D.SaveAsJpeg() 缺少用于设置 Jpeg 质量的参数,并且输出有很多工件。(增加图像的大小确实有一点帮助,但看起来仍然很糟糕)
该参数是否隐藏在 XNA 中的某处?如何提高 jpeg 的质量?
XNA 4.0 API 中没有用于编码 JPEG 图像的质量参数。
作为一种非常迂回的做事方式,您可以创建一个 Silverlight WriteableBitmap
,将数据从渲染目标复制到其中,然后使用Extensions.SaveJpeg
自定义质量级别保存它。
更好的选择可能是简单地保存 PNG 图像。
我同意 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。