WriteableBitmap отображает PNG неправильно

У меня возникают проблемы при рендеринге PNG, которые используют Палитру как "Тип цвета". Вот простой код для воспроизведения проблемы:

private async System.Threading.Tasks.Task Fetch()
{
    HttpClient httpClient = new HttpClient();
    Uri uri = new Uri("http://static.splashnology.com/articles/How-to-Optimize-PNG-and-JPEG-without-Quality-Loss/PNG-Palette.png");
    HttpResponseMessage response = await httpClient.GetAsync(uri);
    if (response.StatusCode == HttpStatusCode.Ok)
    {
        try
        {
            var content = await response.Content.ReadAsBufferAsync();
            WriteableBitmap image = await BitmapFactory.New(1, 1).FromStream(content.AsStream());
            Rect destination = new Rect(0, 0, image.PixelWidth, image.PixelHeight);
            Rect source = new Rect(0, 0, image.PixelWidth, image.PixelHeight);
            WriteableBitmap canvas = new WriteableBitmap(image.PixelWidth, image.PixelHeight);
            canvas.Blit(destination, image, source);
            RadarImage.Source = canvas;
        }
        catch (Exception e)
        {
            System.Diagnostics.Debug.WriteLine(e.Message);
            System.Diagnostics.Debug.WriteLine(e.StackTrace);
        }
    }
}

Если я запускаю этот код с помощью Windows Phone 8.1, изображение отображается с использованием неправильных цветов. Если я проведу тот же тест с использованием PNG, который использует RGB в качестве "Типа цвета", то все работает нормально.

Я заглянул на форум Codeplex и не видел ни одного поста, связанного с этим. Я сообщил об этом как о проблеме, хотя это может быть связано с тем, как я ее отображаю. Есть ли какая-либо ошибка в том, что я использую WriteableBitmap, которая может вызвать неправильный рендеринг?


ОБНОВИТЬ

Согласно этому обсуждению https://writeablebitmapex.codeplex.com/discussions/274445 проблема связана с неожиданным порядком байтов. Эти комментарии были сделаны полтора года назад, поэтому я думаю, что где-то должно быть исправлено...

Изображение, которое отображается неправильно, находится в коде выше.

Этот, используя тот же код, отображается правильно. http://www.queness.com/resources/images/png/apple_ex.png

Единственное различие между этими двумя изображениями заключается в свойстве "Тип цвета". В случае сбоя устанавливается значение "Палитра", а в случае правильной визуализации устанавливается значение "RGB Alpha".

Спасибо! Карлос.

1 ответ

Решение

Проблема, кажется, в расширении FromStream, которое, кажется, переводит png с палитрой в RGBA. Как вы заметили, WriteableBitmap хочет BGRA. Я подозреваю, что FromStream пропускает не-палитровые пиксели pngs. Это позволяет яблоку начинать и заканчивать как BGRA, в то время как обезьяна заканчивает RGBA и рисует с красным и синим в обратном порядке.

Вы можете обойти эту проблему, пропустив FromStream и используя BitmapDecoder, чтобы указать формат, в который вы хотите его декодировать:

// Read the retrieved image's bytes and write them into an IRandomAccessStream
IBuffer buffer = await response.Content.ReadAsBufferAsync();
var randomAccessStream = new InMemoryRandomAccessStream();
await randomAccessStream.WriteAsync(buffer);

// Decode the downloaded image as Bgra8 with premultiplied alpha
// GetPixelDataAsync lets us pass in the desired format and it'll do the magic to translate as it decodes
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(randomAccessStream);
var pixelData = await decoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, new BitmapTransform(), ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.DoNotColorManage);

// Get the decoded bytes
byte[] imageData = pixelData.DetachPixelData();

// And stick them in a WriteableBitmap
WriteableBitmap image = new WriteableBitmap((int)decoder.PixelWidth,(int) decoder.PixelHeight);
Stream pixelStream = image.PixelBuffer.AsStream();

pixelStream.Seek(0, SeekOrigin.Begin);
pixelStream.Write(imageData, 0, imageData.Length);

// And stick it in an Image so we can see it.
RadarImage.Source = image;
Другие вопросы по тегам