zoukankan      html  css  js  c++  java
  • 处理图片(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

  • 相关阅读:
    MAC subline批处理
    Git 所有常用命令
    【React入门】React父子组件传值demo
    【fullGC】内存监控工具
    【dockerFile配置jvm 启动参数】dockerFile 参数解释
    【总结】程序人生,每天进步一点点,以及曾经的梦想
    【记录】Field required a single bean, but 2 were found:
    【maven 】jar包冲突-记一次冲突解决
    PAT甲题题解-1052. Linked List Sorting (25)-排序
    PAT甲题题解-1053. Path of Equal Weight (30)-dfs
  • 原文地址:https://www.cnblogs.com/hebeiDGL/p/3315186.html
Copyright © 2011-2022 走看看