Obsługa obrazów WinRT

Przyjaciel i ja spędziliśmy większą część ostatniej nocy prawie rozdzierając włosy, próbując pracować z niektórymi obrazami w aplikacji metra. Dostaliśmy obrazy do aplikacji z urokiem udziału, a potem chciałem zrobić z nimi inną pracę, przyciąć zdjęcia i zapisać je z powrotem w folderze appdata. To okazało się niezwykle frustrujące.

Moje pytanie na końcu tego wszystkiego brzmi: „Jaki jest właściwy sposób, aby to zrobić, nie czując się, jakbym wbijał kilka niedopasowanych kawałków układanki?”

Gdy udostępniasz wiele obrazów za pomocą aplikacji, pojawiają się jako listaWindows.Storage.StorageFiles. Oto kod używany do tego.

<code>var storageItems = await _shareOperation.Data.GetStorageItemsAsync();

foreach (StorageFile item in storageItems)
{
    var stream = await item.OpenReadAsync();
    var properties = await item.Properties.GetImagePropertiesAsync();

    var image = new WriteableBitmap((Int32)properties.Width, (Int32)properties.Height);
    image.SetSource(stream);

    images.Add(image);
}
</code>

Niektóre wyszukiwania w Internecie wskazywały na to, że obecnieWindows.UI.Xaml.Media.Imaging.WriteableBitmap jest jedyną rzeczą, która umożliwia dostęp do danych pikseli na obrazie.To pytanie zawiera pomocną odpowiedź pełną metod rozszerzenia do zapisywania obrazów w pliku, więc użyliśmy ich.

Nasze problemy były najgorsze, gdy próbowałem otworzyć pliki później. Zrobiłem coś podobnego do wcześniejszego:

<code>var files = await ApplicationData.Current.LocalFolder.GetFilesAsync();

foreach (var file in files)
{
    var fileStream = await file.OpenReadAsync();
    var properties = await file.Properties.GetImagePropertiesAsync();
    var bitmap = new WriteableBitmap((Int32)properties.Width, (Int32)properties.Height);
    bitmap.SetSource(fileStream);

    System.IO.Stream stream = bitmap.PixelBuffer.AsStream();
</code>

Nadchodzi problem. Jak długi jest ten strumień, jeśli chcę z niego bajty?

<code>    // CRASH! Length isn't supported on an IRandomAccessStream.
    var pixels = new byte[fileStream.Length];
</code>

Ok, spróbuj jeszcze raz.

<code>    var pixels = new byte[stream.Length];
</code>

To działa, z wyjątkiem ... jeśli obraz jest skompresowany, strumień jest krótszy niż można by oczekiwać, więc w końcu otrzymasz wyjątek poza granicami. Na razie udawaj, że jest to nieskompresowana mapa bitowa.

<code>    await _stream.ReadAsync(pixels, 0, pixels.Length);
</code>

Zastanów się. Chociaż powiedziałembitmap.SetSource(fileStream); aby odczytać dane, moja tablica bajtów jest nadal pełna zer. Nie mam pojęcia dlaczego. Jeśli zdam to samobitmap w moim interfejsie użytkownika za pośrednictwem przykładowej grupy danych obraz wygląda dobrze. W ten sposób gdzieś znajduje się dane pikseli w tej bitmapie, ale nie mogę tego odczytaćbitmap.PixelBuffer? Dlaczego nie?

W końcu to, co naprawdę się skończyło.

<code>    var decoder = await BitmapDecoder.CreateAsync(BitmapDecoder.PngDecoderId, fileStream);
    var data = await decoder.GetPixelDataAsync();
    var bytes = data.DetachPixelData();

    /* process my data, finally */

} // end of that foreach I started a while ago
</code>

Mam teraz dane obrazu, ale nadal mam duży problem. Aby coś z tym zrobić, muszę przyjąć założenia dotyczące jego formatu. Nie mam pojęcia, czy to rgba, rgb, abgr, bgra, cokolwiek to może być. Jeśli zgaduję, że moje przetwarzanie się nie powiodło. Miałem dziesiątki testów, które wypluwają zero bajtów i uszkodzone obrazy, obrazy do góry nogami (???), niewłaściwe kolory itp. Oczekiwałbym znaleźć niektóre z tych informacji wproperties że mam od powołaniaawait file.Properties.GetImagePropertiesAsync();, ale nie ma szczęścia. Zawiera tylko szerokość i wysokość obrazu oraz kilka innych niepotrzebnych rzeczy. Minimalna dokumentacjatutaj.

Dlaczego więc ten proces jest tak bolesny? Czy to tylko odzwierciedla niedojrzałość bibliotek w tej chwili i czy mogę oczekiwać, że poprawi się? Czy może jest to już jakiś standardowy sposób? Chciałbym, żeby było tak łatwo jak wSystem.Drawing. Dało ci to wszystkie dane, których kiedykolwiek potrzebowałeś, i szczęśliwie poprawnie załadowało dowolny typ obrazu, bez konieczności radzenia sobie ze strumieniami.

questionAnswers(1)

yourAnswerToTheQuestion