×
Namespaces

Variants
Actions

(译)Nokia Imaging SDK — 处理图片

From Nokia Developer Wiki
Jump to: navigation, search

本文为翻译内容,原文链接在底部

WP Metro Icon Multimedia.png
SignpostIcon XAML 40.png
WP Metro Icon WP8.png
Article Metadata

测试基于
SDK: Windows Phone 8.0 SDK, Nokia Imaging SDK Beta 1

兼容于
文章
段博琼 在 11 Oct 2013 创建
最后由 hamishwillee 在 17 Oct 2013 编辑

Contents

简介

高像素的图片,比如分辨率为 7712x4352 的照片,当加载到一个 bitmap 中时会占用相当大的内存。

每个像素会占用 4个字节的内存,所以当没有被压缩时,全部的图片会占用 12800万字节(约122MB)。高像素

图片的另一个问题就是渲染,因为图片不适合windows phone 8 的最大纹理尺寸为 4096x4096 像素,所以

它会被裁切。无论怎样,因为有很多方法来处理高像素图片,所以没有什么好担心的。


显示捕获的照片

首先,把一个 Image 控件放到页面中,用来显示预览:

<!-- Simple preview page -->
<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 中的 EditingSession。

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 image)
{
// Find out the image orientation using the Nokia Imaging SDK, and set BitmapImage
// decode options accordingly
 
using (var memoryStream = new MemoryStream())
{
image.Position = 0;
image.CopyTo(memoryStream);
 
try
{
// Some stream types do not support flushing
 
image.Flush();
}
catch (Exception ex)
{
}
 
memoryStream.Position = 0;
 
IBuffer imageBuffer = memoryStream.GetWindowsRuntimeBuffer();
 
using (var session = new EditingSession(imageBuffer))
{
if (session.Dimensions.Width >= session.Dimensions.Height)
{
_bitmap.DecodePixelWidth = 1280;
_bitmap.DecodePixelHeight = 0; // Will be set automatically
}
else
{
_bitmap.DecodePixelWidth = 0; // Will be set automatically
_bitmap.DecodePixelHeight = 1280;
}
}
}
 
// Set stream as bitmap source
 
image.Position = 0;
 
_bitmap.SetSource(image);
}
 
...
}


可以注意到通常你从平台 APIs 中得到的照片数据是一个 Stream,然后在 Nokia Imaging SDK 中通常采用 IBuffers.

通过下面的方法你可以进行方便的类型转换:

using System.Runtime.InteropServices.WindowsRuntime; // MemoryStream extensions
 
...
 
public class Utilities
{
...
 
/// <summary>
/// Returns a buffer with the contents of the given stream.
/// <param name="stream">Source stream</param>
/// <returns>Buffer with the contents of the given stream</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
{
// Some stream types do not support flushing
 
stream.Flush();
}
catch (Exception ex)
{
}
 
return memoryStream.GetWindowsRuntimeBuffer();
}
}
else
{
return memoryStream.GetWindowsRuntimeBuffer();
}
}
 
/// <summary>
/// Returns a stream with the contents of the given buffer.
/// <param name="stream">Source buffer</param>
/// <returns>Stream with the contents of the given 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;
using System.Runtime.InteropServices.WindowsRuntime;
 
...
 
public class Utilities
{
...
 
/// <summary>
/// Asynchronously scales an image so that the resulting JPEG data does not exceed maxBytes in size and
/// also does not exceed the dimensions given in maxSize.
/// <param name="image">Photo to scale</param>
/// <param name="maxBytes">Maximum size in bytes for the buffer to be returned</param>
/// <param name="maxSize">Maximum size in pixels for the scaled image</param>
/// <returns>JPEG data buffer of the resulting scaled photo/returns>
/// </summary>
private static async Task<IBuffer> ScaleAsync(IBuffer image, uint maxBytes, Size maxSize)
{
// First figure out if the image needs scaling at all
 
var scale = false;
 
using (var editingSession = new EditingSession(image))
{
if (editingSession.Dimensions.Width > maxSize.Width || editingSession.Dimensions.Height > maxSize.Height)
{
scale = true;
}
}
 
if (scale)
{
// Downscale the image
 
var resizeConfiguration = new AutoResizeConfiguration(maxBytes, maxSize,
new Size(0, 0), AutoResizeMode.Automatic, 0, ColorSpace.Yuv420);
 
return await Nokia.Graphics.Imaging.JpegTools.AutoResizeAsync(image, resizeConfiguration);
}
else
{
// No need to compact, use image as it is
 
return image;
}
}
 
...
}

裁切高像素图片

显示高像素图片你可以创建各种 bitmaps 对象,更小或者最大 4096x4096 像素的最大纹理尺寸。 使用 Nokia Imaging SDK 去裁切高像素原图的各个部分是很容易的。

using Nokia.Graphics.Imaging;
using Windows.Foundation;
 
...
 
public class Utilities
{
...
 
/// <summary>
/// Asynchronously crops an area from the photo and returns it as a JPEG data buffer.
/// <param name="image">Photo to take the crop from</param>
/// <param name="cropArea">Crop area</param>
/// <returns>JPEG data buffer of the resulting cropped photo/returns>
/// </summary>
public static async Task<IBuffer> Crop(IBuffer image, Rect cropArea)
{
using (var session = new EditingSession(image))
{
session.AddFilter(FilterFactory.CreateCropFilter(cropArea));
 
return await session.RenderToJpegAsync();
}
}
 
/// <summary>
/// Asynchronously crops an area from the photo and renders it to the given bitmap.
/// <param name="image">Photo to take the crop from</param>
/// <param name="cropArea">Crop area</param>
/// <param name="bitmap">Bitmap to render the resulting cropped photo to</param>
/// </summary>
public static async Task Crop(IBuffer image, Rect cropArea, WriteableBitmap bitmap)
{
using (var session = new EditingSession(image))
{
session.AddFilter(FilterFactory.CreateCropFilter(cropArea));
 
return await session.RenderToWriteableBitmapAsync(bitmap);
}
}
 
...
}


Nokia Wiki 原文链接http://developer.nokia.com/Resources/Library/Lumia/#!imaging/working-with-high-resolution-photos/processing-photos.html

Version Hint

Windows Phone: [[Category:Windows Phone]]
[[Category:Windows Phone 7.5]]
[[Category:Windows Phone 8]]

Nokia Asha: [[Category:Nokia Asha]]
[[Category:Nokia Asha Platform 1.0]]

Series 40: [[Category:Series 40]]
[[Category:Series 40 1st Edition]] [[Category:Series 40 2nd Edition]]
[[Category:Series 40 3rd Edition (initial release)]] [[Category:Series 40 3rd Edition FP1]] [[Category:Series 40 3rd Edition FP2]]
[[Category:Series 40 5th Edition (initial release)]] [[Category:Series 40 5th Edition FP1]]
[[Category:Series 40 6th Edition (initial release)]] [[Category:Series 40 6th Edition FP1]] [[Category:Series 40 Developer Platform 1.0]] [[Category:Series 40 Developer Platform 1.1]] [[Category:Series 40 Developer Platform 2.0]]

Symbian: [[Category:Symbian]]
[[Category:S60 1st Edition]] [[Category:S60 2nd Edition (initial release)]] [[Category:S60 2nd Edition FP1]] [[Category:S60 2nd Edition FP2]] [[Category:S60 2nd Edition FP3]]
[[Category:S60 3rd Edition (initial release)]] [[Category:S60 3rd Edition FP1]] [[Category:S60 3rd Edition FP2]]
[[Category:S60 5th Edition]]
[[Category:Symbian^3]] [[Category:Symbian Anna]] [[Category:Nokia Belle]]

This page was last modified on 17 October 2013, at 03:43.
133 page views in the last 30 days.