处理图片(updated)
??? 高像素的圖片,比如分辨率為 7712x4352 的照片,當加載到一個 bitmap 中時會占用相當大的內存。
每個像素會占用 4個字節的內存,所以當沒有被壓縮時,全部的圖片會占用 12800萬字節(約122MB)。高像素
圖片的另一個問題就是渲染,因為圖片不適合windows phone 8 的最大紋理尺寸為 4096x4096 像素,所以
它會被裁切。無論怎樣,因為有很多方法來處理高像素圖片,所以沒有什么好擔心的。
?
顯示捕獲的照片
???? 首先,把一個 Image 控件放到頁面中,用來顯示預覽:
<!-- 取景框 --> <phone:PhoneApplicationPage x:Class="PreviewPage" ... ><Grid x:Name="LayoutRoot" Background="Transparent"><Grid x:Name="ContentPanel"><Image x:Name="PreviewImage"/></Grid></Grid> </phone:PhoneApplicationPage>?
?然后,在 C# 頁面我們可以用 BitmapImage 的 ?intDecodePixelWidth和?int?DecodePixelHeight 屬性來初始化
?通過void BitmapImage.SetSource(Stream streamSource) 方法調用加載的 JPEG 的數據流 bitmap 的尺寸。
?為了知道 stream 中時一個橫向的 或者 縱向的照片,你可以使用 Nokia Imaging SDK 中的ImageProviderInfo。
using Nokia.Graphics.Imaging; using System.Runtime.InteropServices.WindowsRuntime;...public partial class PreviewPage : PhoneApplicationPage {...private BitmapImage _bitmap = new BitmapImage();public PreviewPage(){InitializeComponent();PreviewImage.Source = _bitmap;...}...private void InitializePreview(Stream stream){// 使用 Nokia Imaging SDK 找出 image 的 orientation 屬性,//并且相應地設置 BitmapImage 解碼選項 stream.Position = 0;using (StreamImageSource source = new StreamImageSource(stream)){ImageProviderInfo info = null;Task.Run(async () => { info = await source.GetInfoAsync(); }).Wait();if (info.ImageSize.Width >= info.ImageSize.Height){_bitmap.DecodePixelWidth = 1536;_bitmap.DecodePixelHeight = 0;}else{_bitmap.DecodePixelWidth = 0;_bitmap.DecodePixelHeight = 1536;}// 把 stream 設置為 bitmap 的源 stream.Position = 0;_bitmap.SetSource(stream);}}... }
?
可以注意到通常你從平臺 APIs 中得到的照片數據是一個 Stream,然后在 Nokia Imaging SDK 中通常采用 IBuffers.
通過下面的方法你可以進行方便的類型轉換:?
using System.Runtime.InteropServices.WindowsRuntime; // MemoryStream 的擴展方法命名空間 ...public class Utilities {.../// <summary>/// 把 Stream 轉換為 IBuffer 對象/// <param name="stream">stream源</param>/// <returns>包含stream數據的IBuffer 對象</returns>/// </summary>public static IBuffer StreamToBuffer(Stream stream){var memoryStream = stream as MemoryStream;if (memoryStream == null){using (memoryStream = new MemoryStream()){stream.Position = 0;stream.CopyTo(memoryStream);try{// 一些流類型不支持 stream.Flush();}catch (Exception ex){}return memoryStream.GetWindowsRuntimeBuffer();}}else{return memoryStream.GetWindowsRuntimeBuffer();}}/// <summary>/// 把 IBuffer 對象轉換為 stream/// <param name="stream">buffer源</param>/// <returns>stream</returns>/// </summary>public static Stream BufferToStream(IBuffer buffer){return buffer.AsStream();}... }
手動縮小圖片的尺寸
實現的方式除了使用 BitmapImage 外,你也可以使用 Nokia Imaging SDK 方便的實現圖片的縮小。Nokia Imaging SDK
可以讓你指定比如 buffer 的最大的 size(bytes) 和 圖片的最大 size(pixels) 來進行操作,并且為你提供了一個新的 data stream
從而你也可以用于其他的目的,而不僅僅把縮小的圖片顯示到屏幕中——比如保存和分享。
?
using Nokia.Graphics.Imaging;...public class Utilities {.../// <summary>/// 異步壓縮一個 image 并且最終 JPEG 數據在字節上不會超過 maxBytes,并且在尺寸上不會超過指定的 maxSize./// <param name="image">壓縮的 Image</param>/// <param name="maxBytes">緩沖區最大字節大小</param>/// <param name="maxSize">壓縮的最大圖片的像素</param>/// <returns>返回壓縮后的 JPEG數據緩沖區 </returns>/// </summary>private static async Task<IBuffer> ScaleAsync(IBuffer image, uint maxBytes, Size maxSize){using (var source = new BufferImageSource(image)){var info = await source.GetInfoAsync();if (info.ImageSize.Width * info.ImageSize.Height > maxSize){var resizeConfiguration = new AutoResizeConfiguration(maxBytes, maxSize,new Size(0, 0), AutoResizeMode.Automatic, 0, ColorSpace.Yuv420);return await Nokia.Graphics.Imaging.JpegTools.AutoResizeAsync(buffer, resizeConfiguration);}else{return image;}}}... }?
?
裁切高像素圖片
顯示高像素圖片你可以創建各種 bitmaps 對象,更小或者等于 4096x4096 像素的最大紋理尺寸。
使用 Nokia Imaging SDK 去裁切高像素原圖的各個部分是很容易的。
using Nokia.Graphics.Imaging; using Windows.Foundation;...public class Utilities {.../// <summary>/// 異步重構(裁切)照片,并且返回一個 JPEG data buffer/// <param name="image">將要重構的照片</param>/// <param name="area">裁切的區域</param>/// <returns>處理后的 JPEG data buffer </returns>/// </summary>public static async Task<IBuffer> Reframe(IBuffer image, Rect area){using (var source = new BufferImageSource(image))using (var effect = new FilterEffect(source)){effect.Filters = new List<IFilter>(){new ReframingFilter(){ReframingArea = area}};using (var renderer = new JpegRenderer(effect)){return await renderer.RenderAsync();}}}/// <summary>/// 異步重構(裁切)照片并且把結果輸出到指定的 bitmap 對象
/// <param name="image">將要重構的照片</param>/// <param name="area">重構的區域</param>/// <param name="bitmap">輸出結果到 bitmap 對象</param>/// </summary>public static async Task Reframe(IBuffer image, Rect area, WriteableBitmap bitmap){using (var source = new BufferImageSource(image))using (var effect = new FilterEffect(source)){effect.Filters = new List<IFilter>(){new ReframingFilter(){ReframingArea = area}};using (var renderer = new WriteableBitmapRenderer(effect, bitmap)){await renderer.RenderAsync();}}}... }
?
?
Nokia Wiki 原文鏈接:http://developer.nokia.com/Resources/Library/Lumia/#!imaging/working-with-high-resolution-photos/processing-photos.html
轉載于:https://www.cnblogs.com/hebeiDGL/p/3315186.html
總結
以上是生活随笔為你收集整理的处理图片(updated)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分辨5线单极性步进电机接头
- 下一篇: 愿闻其翔记(一)