当前位置: 首页 > 编程语言 > C#

如何在C#WinRT-winmd中调整图像大小?Share

时间:2023-04-11 01:05:58 C#

如何在C#WinRT/winmd中调整图像大小?我有一个简单的问题,但到目前为止我还没有找到答案:HowtoresizeajpegimageinaC#WinRT/WinMDprojectandsaveitasanewjpeg?我正在开发一个Windows8Metro应用程序,用于从某个站点下载每日图像并将它们显示在LiveTile上。问题是图像必须小于1024x1024且小于200kB,否则它不会显示在图块上:http://msdn.microsoft.com/en-us/library/windows/apps/hh465403。aspx如果我得到更大的图像,如何调整它的大小以适应LiveTile?我正在考虑简单的调整大小,如width/2和height/2,同时保持纵横比。这里的具体要求是代码必须作为Windows运行时组件运行,因此WriteableBitmapEx库在这里不起作用-它仅适用于常规WinRT项目。WriteableBitmapEx甚至有一个作为winmd项目的分支,但还远未准备好。如何缩放和剪切的示例:asyncprivatevoidBitmapTransformTest(){//硬编码图像位置字符串filePath="C:\Users\Public\Pictures\SamplePictures\fantasy-dragons-wallpaper.jpg";StorageFile文件=等待StorageFile.GetFileFromPathAsync(filePath);如果(文件==null)返回;//从文件创建流并解码图像varfileStream=awaitfile.OpenAsync(Windows.Storage.FileAccessMode.Read);BitmapDecoder解码器=awaitBitmapDecoder.CreateAsync(fileStream);//为新图像创建新的流和编码器InMemoryRandomAccessStreamras=newInMemoryRandomAccessStream();BitmapEncoderenc=awaitBitmapEncoder.CreateForTranscodingAsync(ras,decoder);//将整个位图转换为100pxx100px位图enc.BitmapTransform.ScaledHeight=100;enc.BitmapTransform.ScaledWidth=100;BitmapBounds边界=newBitmapBounds();bounds.Height=50;bounds.Width=50;界限.X=50;界限.Y=50;enc.BitmapTransform.Bounds=边界;//写入流try{awaitenc.FlushAsync();}catch(Exceptionex){strings=ex.ToString();}//将流渲染到屏幕BitmapImagebImg=newBitmapImage();bImg.SetSource(ras);img.Source=bImg;//xaml中的图像元素}更简单的代码来调整图像大小而不是裁剪以下代码使用(varsourceStream=awaitsourceFile.OpenAsync(FileAccessMode.Read)){BitmapDecoderdecoder=awaitBitmapDecoder.CreateAsync(sourceStream);将图像重新缩放为80x80BitmapTransformtransform=newBitmapTransform(){ScaledHeight=80,ScaledWidth=80};PixelDataProviderpixelData=awaitdecoder.GetPixelDataAsync(BitmapPixelFormat.Rgba8,BitmapAlphaMode.Straight,transform,ExifOrientationMode.RespectExifOrientation,ColorManagementMode.DoNotColorManage);使用(vardestinationStream=awaitdestinationFile.OpenAsync(FileAccessMode.ReadWrite)){BitmapEncoderencoder=awaitBitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId,destinationStream);encoder.SetPixelData(BitmapPixelFormat.Rgba8,BitmapAlphaMode.Premultiplied,80,80,96,96,pixelData.DetachPixelData());等待编码器.Flush}Async}();这是我在大量谷歌搜索和试错编码后得出的解决方案:这里的目标是找出如何在WinRT中操作图像,尤其是在后台任务中。后台任务比常规WinRT项目更受限制,因为它们必须属于Windows运行时组件类型。NuGet目标WinRT上99%的可用库仅针对默认的WinRT项目,因此它们不能用于Windows运行时组件项目。起初我尝试使用著名的WriteableBitmapEx库——将必要的代码移植到我的winmd项目中。甚至还有一个针对winmd的WBE项目分支,但尚未完成。我在将[ReadOnlyArray]、[WriteOnlyArray]属性添加到数组类型的方法参数之后进行编译,并将项目命名空间更改为不以“Windows”开头的名称(winmd项目限制)。即使我能够在我的后台任务项目中使用这个库,它也不会工作,因为正如我发现的那样,WriteableBitmap必须在UI线程中实例化,据我所知,这在后台任务中是不可能的。同时,我还找到了这篇关于WinRT图像处理的MSDN文章。大多数示例仅在JavaScript部分,因此我必须先将其转换为C#。我还在StackOverflow上找到了这篇关于WinRT图像处理的有用文章。内部静态异步任务LoadTileImageInternalAsync(stringimagePath){stringtileName=imagePath.GetHashedTileName();StorageFileorigFile=awaitApplicationData.Current.LocalFolder.GetFileAsync(imagePath);//为新的图块图像文件打开文件StorageFiletileFile=awaitApplicationData.Current.LocalFolder.CreateFileAsync(tileName,CreationCollisionOption.ReplaceExisting);using(IRandomAccessStreamtileStream=awaittileFile.OpenAsync(FileAccessMode.ReadWrite)){//从原始图像中获取宽度和高度IRandomAccessStreamWithContentTypestream=awaitorigFile.OpenReadAsync();ImageProperties属性=awaitorigFile.Properties.GetImagePropertiesAsync();uintwidth=properties.Width;uintheight=properties.Height;//为输入文件获取正确的解码器-jpg/png/gifBitmapDecoderdecoder=awaitGetProperDecoder(stream,imagePath);如果(解码器==null)返回;//不应该发生//获取实际解码的字节数组图片PixelDataProviderdata=awaitdecoder.GetPixelDataAsync();byte[]bytes=data.DetachPixelData();//创建用于保存瓦片图像的编码器BitmapPropertySetpropertySet=newBitmapPropertySet();//创建表示目标jpeg质量的类-有点晦涩,但它有效propertySet.Add("ImageQuality",qualityValue);//创建目标jpeg解码器BitmapEncoderbe=awaitBitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId,tileStream,propertySet);be.SetPixelData(BitmapPixelFormat.Rgba8,BitmapAlphaMode.Straight,width,height,96.0,96.0,bytes);//裁剪图像,如果它太大if(width>MaxImageWidth||height>MaxImageHeight){BitmapBoundsbounds=newBitmapBounds();如果(宽度>MaxImageWidth){bounds.Width=MaxImageWidth;bounds.X=(width-MaxImageWidth)/2;}否则bounds.Width=width;如果(高度>MaxImageHeight){bounds.Height=MaxImageHeight;bounds.Y=(height-MaxImageHeight)/2;}否则bounds.Height=height;be.BitmapTransform.Bounds=边界;}//将目标jpg保存到文件中awaitbe.FlushAsync();}}privatestaticasyncTaskGetProperDecoder(IRandomAccessStreamWithContentTypestream,stringimagePath){stringext=Path.GetExtension(imagePath);switch(ext){case".jpg":case".jpeg":returnawaitBitmapDecoder.CreateAsync(BitmapDecoder.JpegDecoderId,stream);case".png":returnawaitBitmapDecoder.CreateAsync(BitmapDecoder.PngDecoderId,stream);case".gif":returnawaitBitmapDecoder.CreateAsync(BitmapDecoder.GifDecoderId,stream);}返回空值;在此示例中,我们打开一个文件,将其解码为字节数组,然后将其编码回具有不同大小/格式/质量的新文件。结果是它甚至可以使用Windows运行时组件类,并且没有WriteableBitmapEx库完全运行图像处理。这是较短的版本,没有访问像素数据的开销。使用(varsourceFileStream=awaitsourceFile.OpenAsync(Windows.Storage.FileAccessMode.Read))使用(vardestFileStream=awaitdestinationFile.OpenAsync(FileAccessMode.ReadWrite)){BitmapEncoderenc=awaitBitmapEncoder.CreateForTranscodingAsync(destFileStream,decoder);enc.BitmapTransform.ScaledWidth=newWidth;enc.BitmapTransform.ScaledHeight=newHeight;等待enc.FlushAsync();等待destFileStream.FlushAsync();清除这个,我有一个JPG字节数组并尝试了给定的答案......我无法让它工作所以我做了一个新答案......希望这会帮助别人......我是将JPG转换为250/250像素privateasyncTaskByteArrayToBitmapImage(byte[]byteArray){BitmapImageimage=newBitmapImage();使用(InMemoryRandomAccessStreamstream=newInMemoryRandomAccessStream()){使用(DataWriterwriter=newDataWriter(stream.GetOutputStreamAt(0))){writer.WriteBytes((byte[])byteArray);writer.StoreAsync().GetResults();}我mage.SetSource(流);}image.DecodePixelHeight=250;image.DecodePixelWidth=250;返回图像;如果你想要高质量的图像然后在BitmapTransform中添加InterpolationMode=BitmapInterpolationMode.Fant,这里是示例`publicstaticasyncTaskResizeImage(Windows.Storage.StorageFileimgeTOBytes,intmaxWidth,intmaxHeight){以上是C#学习教程:如何在C#WinRT/winmd中调整图像大小?所有分享的内容,如果对你有用,需要进一步了解C#学习教程,希望大家多多关注——using(varsourceStream=awaitimgeTOBytes.OpenAsync(FileAccessMode.Read)){BitmapDecoderdecoder=awaitBitmapDecoder.CreateAsync(sourceStream);双宽度比率=(double)maxWidth/decoder.OrientedPixelWidth;双heightRatio=(double)maxHeight/decoder.OrientedPixelHeight;双scaleRatio=Math.Min(widthRatio,heightRatio);uintaspectHeight=(uint)Math.Floordouble)decoder.OrientedPixelHeight*scaleRatio);uintaspectWidth=(uint)Math.Floor((double)decoder.OrientedPixelWidth*scaleRatio);BitmapTransformtransform=newBitmapTransform(){InterpolationMode=BitmapInterpolationMode.Fant,ScaledHeight=aspectHeight,ScaledWidth=aspectWidth};PixelDataProviderpixelData=awaitdecoder.GetPixelDataAsync(BitmapPixelFormat.Rgba8,BitmapAlphaMode.Premultiplied,transform,ExifOrientationMode.RespectExifOrientation,ColorManagementMode.DoNotColorManage);使用(vardestinationStream=awaitimgeTOBytes.OpenAsync(FileAccessMode.ReadWrite)){BitmapEncoderencoder=awaitBitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId,destinationStream);encoder.SetPixelData(BitmapPixelFormat.Rgba8,BitmapAlphaMode.Straight,aspectWidth,aspectHeight,96,96,pixelData)等待编码器.FlushAsync();}}`本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处: