问题描述:

I have code that allows the user to select an image using file picker & I convert the image to a byte array so that it can be serialized. When viewing the collection of images, if I have too many, the app crashes & will not load. When I debug using visual studios it runs fines but takes a long time to load the images. I believe it times out because it's taking to long to load. After obtaining the storage file. How do I lower the quality of the BitmapImage so that when serialized it doesn't take as long to load?

 private async void AddPic_OnClick(object sender, RoutedEventArgs e)

{

ImagePath = string.Empty;

FileOpenPicker openPicker = new FileOpenPicker();

openPicker.ViewMode = PickerViewMode.Thumbnail;

openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;

openPicker.FileTypeFilter.Clear();

openPicker.FileTypeFilter.Add(".bmp");

openPicker.FileTypeFilter.Add(".jpg");

openPicker.FileTypeFilter.Add(".jpeg");

openPicker.FileTypeFilter.Add(".png");

// Launch file open picker and caller app is suspended and may be terminated

var file = await openPicker.PickSingleFileAsync();

if (file != null)

{

var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);

var image = new BitmapImage();

image.SetSource(stream);

xamlimg.Source = image;

_myClass.ImageBytes = await App.DataModel.GetBytesAsync(file);

}

}

Other Class details:

public BitmapImage Image

{

get

{

if (ImageBytes == null)

return null;

if (_Image == null)

_Image = new BitmapImage();

using (var stream = new InMemoryRandomAccessStream())

{

stream.WriteAsync(ImageBytes.AsBuffer()).Completed = (i, j) =>

{

stream.Seek(0);

_Image.SetSource(stream);

};

}

return _Image;

}

}

[JsonProperty]

public byte[] ImageBytes { get; set; }

public async Task<byte[]> GetBytesAsync(StorageFile file)

{

byte[] fileBytes = null;

if (file == null) return null;

using (var stream = await file.OpenReadAsync())

{

fileBytes = new byte[stream.Size];

using (var reader = new DataReader(stream))

{

await reader.LoadAsync((uint) stream.Size);

reader.ReadBytes(fileBytes);

}

}

return fileBytes;

}

网友答案:

You could decode it and scale it to be smaller. So, once you have the result from the file picker, you could do:

using (IRandomAccessStream fileStream = await result.OpenAsync(FileAccessMode.Read))
{
    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
    using (var encoderStream = new InMemoryRandomAccessStream())
    {
        BitmapEncoder encoder = await BitmapEncoder.CreateForTranscodingAsync(encoderStream, decoder);
        var newHeight = decoder.PixelHeight / 2;
        var newWidth = decoder.PixelWidth / 2;
        encoder.BitmapTransform.ScaledHeight = newHeight;
        encoder.BitmapTransform.ScaledWidth = newWidth;

        await encoder.FlushAsync();

        byte[] pixels = new byte[newWidth * newHeight * 4];

        await encoderStream.ReadAsync(pixels.AsBuffer(), (uint)pixels.Length, InputStreamOptions.None);
}

Byte array pixels should then be smaller for serialization, but the image will be in worse quality.

相关阅读:
Top