Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何正确调整图像大小/重新压缩图像_C#_Image Processing_Compression_Windows Store Apps_Image Resizing - Fatal编程技术网

C# 如何正确调整图像大小/重新压缩图像

C# 如何正确调整图像大小/重新压缩图像,c#,image-processing,compression,windows-store-apps,image-resizing,C#,Image Processing,Compression,Windows Store Apps,Image Resizing,在过去的10-12个小时里,我一直在研究如何在正在开发的Windows应用商店应用程序中正确地将下载的web图像缩小到更小的大小和C#像素 无论我做什么,我都会在最终的图像上得到一些瑕疵,比如“半张图片”、灰色/相同颜色的区域,以及类似的东西。比如,如果流没有被正确地刷新,尽管我相信已经这样做了(在下面的代码中没有这样做,因为它在没有它的情况下工作…) 这是我检索图像的方法-此部分有效,但包含在此处以确保所有信息都在此处(请参见下面的代码): 获取图像的URL 使用HttpWebRequest获

在过去的10-12个小时里,我一直在研究如何在正在开发的Windows应用商店应用程序中正确地将下载的web图像缩小到更小的大小和C#像素

无论我做什么,我都会在最终的图像上得到一些瑕疵,比如“半张图片”、灰色/相同颜色的区域,以及类似的东西。比如,如果流没有被正确地刷新,尽管我相信已经这样做了(在下面的代码中没有这样做,因为它在没有它的情况下工作…)

这是我检索图像的方法-此部分有效,但包含在此处以确保所有信息都在此处(请参见下面的代码):

  • 获取图像的URL
  • 使用HttpWebRequest获取响应
  • 创建流以获取响应流
  • 创建空存储文件并打开以进行写入
  • 将响应流复制到存储文件
  • 关闭一切
  • 从这里开始,我需要做以下工作:

  • 确定大小(例如,使用位图解码器)
  • 如果图像的宽度超过一定量(例如700像素),则必须调整其大小
  • 不管怎样,文件总是太大,需要进一步压缩
  • 图像需要保存为jpg,图像质量设置为中等/半高
  • 我已经尝试过很多事情,包括用BitmapEncoder/BitmapDecoder乱搞,但不管怎样,我还是得到了半处理的图像

    有人能帮我找到压缩和调整图像大小的正确方法吗

    当前状态下的我的代码:

    using (var response = await HttpWebRequest.CreateHttp(internetUri).GetResponseAsync())
    {
        using (var stream = response.GetResponseStream())
        {
            var imageFolder = await localFolder.CreateFolderAsync(
                   CachedImagesFolderEndFolderPath, CreationCollisionOption.OpenIfExists);
    
            string fileName = string.Format("{0}.jpg", 
                   Path.GetFileNameWithoutExtension(Path.GetRandomFileName()));
    
            var file = await imageFolder.CreateFileAsync(fileName, 
                   CreationCollisionOption.ReplaceExisting);
    
            using (var filestream = await file.OpenStreamForWriteAsync())
            {
                await stream.CopyToAsync(filestream);
            }
        }
    }
    

    中提供了以下解决方案:

    我以前的解决方案的问题似乎是我没有正确地关闭流,并且没有正确的设置

    基本上,解决方案包含以下条款中的要素:

    在代码的主要部分,我对每个需要下载、调整大小和压缩的图像进行了以下调用:

    主代码 请注意,我很清楚在分配字符串值然后再次设置它时“不是最佳做法”。这是尚未进行微调的原型代码

    var img = await ArticleStorage.GetLocalImageAsync(src);
    img = await ArticleStorage.ResizeAndCompressLocalImage(img);
    
    ArticleStorage中方法的源代码 public const string CachedImagesFolderFullPath=“ms-appdata:///local/cache/"; public const string CachedImagesFolderEndFolderPath=“cache”; public const string OfflinePhotoImgPath=“ms-appx:///Assets/OfflinePhoto.png"; public const int MaximumColumnWidth=700; 公共静态异步任务GetLocalImageAsync(字符串internetUri) { if(string.IsNullOrEmpty(internetUri)) { 返回null; } //如果本地文件夹不存在,则显示默认图像 var localFolder=ApplicationData.Current.localFolder; if(localFolder==null) { 返回脱机photoimgpath; } //默认为脱机照片 字符串src=OfflinePhotoImgPath; 尝试 { 使用(var response=wait-HttpWebRequest.CreateHttp(internetUri) .GetResponseAsync()) { 使用(var stream=response.GetResponseStream()) { //新的随机文件名(例如x53fjtje.jpg) string fileName=string.Format(“{0}.jpg”, Path.GetFileNameWithoutExtension(Path.GetRandomFileName()); var imageFolder=wait localFolder.CreateFolderAsync( CachedImagesFolderEndFolderPath, CreationCollisionOption.OpenIfExists); var file=wait imageFolder.CreateFileAsync(文件名, CreationCollisionOption.ReplaceExisting); //将字节从流复制到本地文件 //不更改任何文件信息 使用(var filestream=await file.OpenStreamForWriteAsync()) { 等待stream.CopyToAsync(filestream); //将本地路径发送回映像 //(包括"女士")-appdata:///local/cache/') 返回string.Format(CachedImagesFolderFullPath+“{0}”, 文件名); } } } } 捕获(例外) { //是通过设置隐式处理的 //src的初始值的 } //如果未成功,请返回默认脱机映像 返回src; } 公共静态异步任务ResizeAndCompressLocalImage(字符串imgSrc) { //删除“ms”-appdata:///local/cache/“从小路上。。。 字符串sourcepathShort=imgSrc.Replace( CachedImagesFolderFullPath, 字符串(空); //获取缓存的图像文件夹 var folder=wait ApplicationData.Current .LocalFolder .GetFolderAsync( CachedImagesFolderEndFolderPath); //获取新的随机名称(例如“555jkdhr5.jpg”) var targetPath=string.Format(“{0}.jpg”, Path.GetFileNameWithoutExtension( GetRandomFileName()); //检索源文件并创建目标文件 var sourceFile=await folder.GetFileAsync(sourcepathShort); var targetFile=await folder.CreateFileAsync(targetPath); 使用(var sourceFileStream=await sourceFile.OpenAsync)( Windows.Storage.FileAccessMode.Read) { 使用(var destFileStream=await targetFile.OpenAsync)( FileAccessMode.ReadWrite) { //准备对源图像进行解码 BitmapDecoder decoder=等待BitmapDecoder.CreateAsync( 源文件流); //了解图像是否需要调整大小 双比例宽度=(双)解码器.PixelWidth/ 布局尺寸。最大列宽; 双比例
    public const string CachedImagesFolderFullPath = "ms-appdata:///local/cache/";
    public const string CachedImagesFolderEndFolderPath = "cache";
    public const string OfflinePhotoImgPath = "ms-appx:///Assets/OfflinePhoto.png";
    public const int MaximumColumnWidth = 700;
    
    public static async Task<string> GetLocalImageAsync(string internetUri)
    {
        if (string.IsNullOrEmpty(internetUri))
        {
            return null;
        }
    
        // Show default image if local folder does not exist
        var localFolder = ApplicationData.Current.LocalFolder;
        if (localFolder == null)
        {
            return OfflinePhotoImgPath;
        }
    
        // Default to offline photo
        string src = OfflinePhotoImgPath;
    
        try
        {
            using (var response = await HttpWebRequest.CreateHttp(internetUri)
                                                      .GetResponseAsync())
            {
                using (var stream = response.GetResponseStream())
                {
                    // New random filename (e.g. x53fjtje.jpg)
                    string fileName = string.Format("{0}.jpg",
                        Path.GetFileNameWithoutExtension(Path.GetRandomFileName()));
    
                    var imageFolder = await localFolder.CreateFolderAsync(
                        CachedImagesFolderEndFolderPath, 
                        CreationCollisionOption.OpenIfExists);
    
                    var file = await imageFolder.CreateFileAsync(fileName, 
                        CreationCollisionOption.ReplaceExisting);
    
                    // Copy bytes from stream to local file 
                    // without changing any file information
                    using (var filestream = await file.OpenStreamForWriteAsync())
                    {
                        await stream.CopyToAsync(filestream);
    
                        // Send back the local path to the image 
                        // (including 'ms-appdata:///local/cache/')
                        return string.Format(CachedImagesFolderFullPath + "{0}", 
                             fileName);
                    }
                }
            }
        }
        catch (Exception)
        {
            // Is implicitly handled with the setting 
            // of the initilized value of src
        }
    
        // If not succesfull, return the default offline image
        return src;
    }
    
    public static async Task<string> ResizeAndCompressLocalImage(string imgSrc)
    {
        // Remove 'ms-appdata:///local/cache/' from the path ... 
        string sourcepathShort = imgSrc.Replace(
                                     CachedImagesFolderFullPath,
                                     string.Empty);
    
        // Get the cached images folder
        var folder = await ApplicationData.Current
                              .LocalFolder
                              .GetFolderAsync(
                                   CachedImagesFolderEndFolderPath);
    
        // Get a new random name (e.g. '555jkdhr5.jpg')
        var targetPath = string.Format("{0}.jpg",
                              Path.GetFileNameWithoutExtension(
                                  Path.GetRandomFileName()));
    
        // Retrieve source and create target file
        var sourceFile = await folder.GetFileAsync(sourcepathShort);
        var targetFile = await folder.CreateFileAsync(targetPath);
    
        using (var sourceFileStream = await sourceFile.OpenAsync(
                       Windows.Storage.FileAccessMode.Read))
        {
            using (var destFileStream = await targetFile.OpenAsync(
                       FileAccessMode.ReadWrite))
            {
                // Prepare decoding of the source image
                BitmapDecoder decoder = await BitmapDecoder.CreateAsync(
                                                  sourceFileStream);
    
                // Find out if image needs resizing
                double proportionWidth = (double)decoder.PixelWidth /
                                         LayoutDimensions.MaximumColumnWidth;
    
                double proportionImage = decoder.PixelHeight / 
                                         (double)decoder.PixelWidth;
    
                // Get the new sizes of the image whether it is the same or should be resized
                var newWidth = proportionWidth > 1 ? 
                               (uint)(MaximumColumnWidth) : 
                               decoder.PixelWidth;
    
                var newHeight = proportionWidth > 1 ? 
                                (uint)(MaximumColumnWidth * proportionImage) : 
                                decoder.PixelHeight;
    
                // Prepare set of properties for the bitmap
                BitmapPropertySet propertySet = new BitmapPropertySet();
    
                // Set ImageQuality
                BitmapTypedValue qualityValue = new BitmapTypedValue(0.75, 
                                                        PropertyType.Single);
                propertySet.Add("ImageQuality", qualityValue);
    
                //BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(
                                                destFileStream, decoder);
                BitmapEncoder enc = await BitmapEncoder.CreateAsync(
                                              BitmapEncoder.JpegEncoderId, 
                                              destFileStream, propertySet);
    
                // Set the new dimensions
                enc.BitmapTransform.ScaledHeight = newHeight;
                enc.BitmapTransform.ScaledWidth = newWidth;
    
                // Get image data from the source image
                PixelDataProvider pixelData = await decoder.GetPixelDataAsync();
    
                // Copy in all pixel data from source to target
                enc.SetPixelData(
                    decoder.BitmapPixelFormat,
                    decoder.BitmapAlphaMode,
                    decoder.PixelWidth, 
                    decoder.PixelHeight, 
                    decoder.DpiX, 
                    decoder.DpiY, 
                    pixelData.DetachPixelData()
                    );
    
                // Make the encoder process the image
                await enc.FlushAsync();
    
                // Write everything to the filestream 
                await destFileStream.FlushAsync();
            }
        }
    
        try
        {
            // Delete the source file
            await sourceFile.DeleteAsync();
        }
        catch(Exception)
        {
        }
    
        // Return the new path 
        // including "ms-appdata:///local/cache/"
        return string.Format(CachedImagesFolderFullPath + "{0}", 
             targetPath);
    }