Как установить качество для RenderTarget2D.SaveAsJpeg ()? - PullRequest
0 голосов
/ 10 февраля 2011
public void SaveAsJpeg(Stream stream, int width, int height)

В RenderTarget2D.SaveAsJpeg () отсутствует параметр для установки качества Jpeg, и на выходе есть много артефактов.(увеличение размера изображения немного помогает, но все равно выглядит плохо)

Этот параметр скрыт где-то в XNA?Как я могу улучшить качество JPEG?

Ответы [ 2 ]

2 голосов
/ 10 февраля 2011

В XNA 4.0 API отсутствует параметр качества для кодирования изображений JPEG.

В качестве весьма обыденного способа вы можете создать Silverlight WriteableBitmap, скопировать данныевне вашей цели рендеринга и затем используйте Extensions.SaveJpeg, чтобы сохранить его с пользовательским уровнем качества.

Лучшей альтернативой может быть простое сохранение изображения PNG.

0 голосов
/ 07 июня 2011

Я согласен с Эндрю Расселом в том, что гораздо лучшая альтернатива - просто сохранить в PNG, но если вам просто нужно сохранить в jpg, то есть гораздо лучший способ, чем использовать WriteableBitmap.

Что вы можете сделать, это создать пустой растровый объект и перенести данные текстуры поверх него, чтобы выполнить преобразование Texture2D в растровое изображение. Просто скопируйте снизу:

    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, но без предварительного умножения альфа.

...