C# 返回图片的字节流byte[]

本文介绍了一种将图片转换为字节流的方法,包括从本地文件读取和通过URL下载图片并转换的过程。该方法适用于需要在网络上传输图片或进行图片存储的应用场景。
            /// <summary>  
            /// 返回图片的字节流byte[]  
            /// </summary>  
            /// <param name="imagePath"></param>  
            /// <param name="webClient"></param>  
            /// <returns></returns>  
            public static byte[] getImageByte(string imagePath, WebClient webClient)  
            {  
                byte[] imgByte = null;  
                try  
                {  
                    //MessageBox.Show("getImageByte");  
                    //Stopwatch stopwatch = new Stopwatch();  
                    //stopwatch.Start();  
                    //DateTime dateStart = DateTime.Now;  
      
                    if (PubFunc.UrlDiscern(imagePath))  
                    {  
                        Bitmap bt = new Bitmap(webClient.OpenRead(imagePath));  
                        imgByte = PubFunc.ImgToByte(bt);  
                    }  
                   
<think>我们已知用户希望使用C#压缩字节流中的图片。参考提供的引用内容,我们可以总结出以下关键点: 1. 引用[1]展示了通过改变图片质量和尺寸来压缩图片,并保存为文件。 2. 引用[2]展示了当图片大小超过1MB时,从流中读取字节数组,然后转换为Bitmap进行压缩,并保存到文件。 3. 引用[3]展示了一个压缩方法,并提到对JPG压缩效果最好。 用户需求是压缩字节流中的图片,而不是从文件读取。因此,我们需要从字节数组(byte[])开始,进行压缩,并返回压缩后的字节数组。 步骤: 1. 将字节数组转换为Image对象(或Bitmap)。 2. 根据压缩参数(如质量、尺寸)进行压缩处理。 3. 将压缩后的图片保存到另一个字节数组中。 注意:压缩图片通常涉及调整尺寸和/或调整JPEG质量。对于其他格式(如PNG)压缩方式可能不同,但用户提到对JPG效果最好,所以我们可以优先考虑JPG压缩。 我们需要一个方法,输入为原始图片的字节数组,以及可选的压缩参数(如目标质量、最大宽度/高度等),输出为压缩后的字节数组。 参考引用[2]中的代码片段,他们使用了`ImageHelper.Compress`方法,但未给出具体实现。因此,我们需要自己实现压缩逻辑。 实现思路: 1. 从字节数组创建Image对象。 2. 如果指定了缩放尺寸,则按比例调整图片大小。 3. 设置图片的压缩质量(对于JPEG)。 4. 使用编码器参数将压缩质量设置到编码器。 5. 将压缩后的图片保存到内存流(MemoryStream)中,并返回字节数组。 注意:压缩质量参数(0-100)仅适用于JPEG格式。对于其他格式,我们可以忽略质量参数,或者采用其他压缩方式(如PNG压缩级别)。 因此,我们可以编写一个通用的压缩方法,但需要指定输出格式(如ImageFormat.Jpeg)。如果用户没有指定,我们可以根据原始格式或默认使用JPEG。 由于用户是从字节流中压缩,可能不知道原始格式,但我们可以通过原始字节数组获取图像格式。不过,为了简化,我们可以要求用户指定输出格式,或者默认使用JPEG(因为压缩效果最好)。 方法签名: ```csharp public static byte[] CompressImage(byte[] originalBytes, int quality = 80, int? maxWidth = null, int? maxHeight = null, ImageFormat format = null) ``` 步骤详解: 1. 使用`MemoryStream`将原始字节数组转换为`Image`对象。 2. 如果指定了最大宽度或最大高度,则计算缩放后的尺寸(保持比例)。 3. 创建一个新的`Bitmap`对象作为画布,尺寸为缩放后的尺寸(或原始尺寸)。 4. 使用`Graphics`对象将原始图片绘制到新位图上(进行缩放)。 5. 获取图像编码器(如JPEG编码器)。 6. 设置编码器参数,特别是质量参数。 7. 将压缩后的图像保存到另一个`MemoryStream`中。 8. 返回该流的字节数组。 注意:由于涉及到资源释放,需要使用`using`语句确保资源被释放。 下面我们实现这个方法:</think>### C# 压缩图片字节流的实现方案 在 C# 中压缩字节流中的图片,核心步骤包括: 1. 将字节流转换为 `Image` 对象 2. 设置压缩参数(质量、尺寸等) 3. 使用编码器参数进行压缩 4. 将压缩结果转回字节流 #### 完整实现代码 ```csharp using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; public class ImageCompressor { /// <summary> /// 压缩图片字节流 /// </summary> /// <param name="originalBytes">原始图片字节流</param> /// <param name="quality">压缩质量 (1-100)</param> /// <param name="maxWidth">最大宽度(可选)</param> /// <param name="maxHeight">最大高度(可选)</param> /// <returns>压缩后的字节流</returns> public static byte[] CompressImageBytes(byte[] originalBytes, int quality = 80, int? maxWidth = null, int? maxHeight = null) { using (var inputStream = new MemoryStream(originalBytes)) using (var originalImage = Image.FromStream(inputStream)) { // 计算新尺寸(保持宽高比) var newSize = CalculateNewSize(originalImage.Size, maxWidth, maxHeight); // 创建目标位图 using (var compressedBitmap = new Bitmap(newSize.Width, newSize.Height)) using (var outputStream = new MemoryStream()) { // 设置高质量绘制参数 using (var graphics = Graphics.FromImage(compressedBitmap)) { graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.DrawImage(originalImage, 0, 0, newSize.Width, newSize.Height); } // 配置编码参数(重点设置质量) var encoderParams = new EncoderParameters(1); encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, quality); // 获取 JPEG 编码器 var jpegEncoder = GetEncoder(ImageFormat.Jpeg); // 保存到输出流 compressedBitmap.Save(outputStream, jpegEncoder, encoderParams); return outputStream.ToArray(); } } } /// <summary> /// 计算保持比例的新尺寸 /// </summary> private static Size CalculateNewSize(Size originalSize, int? maxWidth, int? maxHeight) { if (!maxWidth.HasValue && !maxHeight.HasValue) return originalSize; var width = originalSize.Width; var height = originalSize.Height; var ratio = (double)width / height; // 仅限制宽度 if (maxWidth.HasValue && width > maxWidth.Value) { width = maxWidth.Value; height = (int)(width / ratio); } // 检查高度限制 if (maxHeight.HasValue && height > maxHeight.Value) { height = maxHeight.Value; width = (int)(height * ratio); } return new Size(width, height); } /// <summary> /// 获取图像编码器 /// </summary> private static ImageCodecInfo GetEncoder(ImageFormat format) { var codecs = ImageCodecInfo.GetImageEncoders(); foreach (var codec in codecs) { if (codec.FormatID == format.Guid) return codec; } return null; } } ``` #### 使用示例 ```csharp // 原始图片字节流(来自文件/网络等) byte[] originalBytes = File.ReadAllBytes("original.jpg"); // 执行压缩(质量80%,限制宽度为800px) byte[] compressedBytes = ImageCompressor.CompressImageBytes( originalBytes: originalBytes, quality: 80, maxWidth: 800 ); // 保存或使用压缩结果 File.WriteAllBytes("compressed.jpg", compressedBytes); ``` ### 关键参数说明 1. **质量参数**:`quality` (1-100) - 推荐值:`80`(体积显著减小,质量损失较小) - 值越小压缩率越高,但图像质量越低 2. **尺寸参数**: - `maxWidth`/`maxHeight`:按比例缩放图片 - 建议同时设置宽高限制,避免比例失调 3. **格式选择**: - 对照片类图像优先使用 `ImageFormat.Jpeg` - 对带透明通道的图像使用 `ImageFormat.Png` ### 性能优化建议 1. **大图处理**:当原始尺寸超过 4096px 时,建议分步处理: ```csharp // 第一步:快速缩放到接近目标尺寸 // 第二步:精细压缩到最终尺寸 ``` 2. **资源释放**: - 所有 `IDisposable` 对象(`Image`, `Graphics`, `MemoryStream`)必须使用 `using` 包裹 - 避免在循环中重复创建编码器(可静态缓存) 3. **异常处理**: - 捕获 `ArgumentException`(无效字节流) - 处理 `OutOfMemoryException`(超大图片) > **注意**:JPEG 编码器对质量参数最敏感,压缩效果最佳(如引用[3]所述)[^3]。对于 PNG 格式,需改用 `ImageFormat.Png` 并移除质量参数设置。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值