当前位置: 首页 > news >正文

【C#】PNG 和 JPG、JPEG的应用以及三种格式的区别?

PNG(Portable Network Graphics)、JPG(也称为JPEG,Joint Photographic Experts Group)是两种常用的图像文件格式,它们各有特点,适用于不同的场景。

三种格式的区别

  • 压缩方式

    • PNG:采用无损压缩算法。这意味着无论你保存、编辑多少次,图像质量都不会下降。
    • JPG/JPEG:使用有损压缩算法。在保存为JPG时,你可以选择压缩比例,更高的压缩率意味着更小的文件大小,但同时也会导致图像质量下降。
  • 透明度支持

    • PNG:支持透明度。PNG有两种主要形式:PNG-8(支持256色和一个透明通道)和PNG-24(支持全彩色和一个alpha通道,允许不同程度的透明)。这使得它非常适合用于需要背景透明效果的图像,如网站图标、标志等。
    • JPG/JPEG:不支持透明度。所有JPG图像都必须有一个背景颜色(通常为白色或其它纯色),因此不适合需要透明背景的应用场景。
  • 用途

    • PNG:由于其无损质量和对透明度的支持,常用于保存图形设计、文本较多的图像、需要高质量输出的设计稿以及任何需要透明背景的场合。
    • JPG/JPEG:因其高效的压缩比,适合用来存储色彩丰富的照片或复杂的图像,特别是在网络上传输或展示时,因为这些场景往往更看重文件大小而非绝对的图像质量。

在处理图像时关于透明度的区别

当你处理包含透明区域的图像时,PNG格式通常是首选,因为它可以准确地保存透明度信息。而JPG格式则无法保存透明度信息,如果你将一个具有透明背景的PNG图像另存为JPG格式,软件通常会要求你指定一种背景颜色来填充原本透明的部分。

综上所述,在需要保持最佳图像质量和/或透明背景的情况下,PNG是一个更好的选择;而在追求较小文件尺寸且不需要透明背景的照片存储中,JPG更为合适。

在C#中PNG 和 JPG、JPEG的应用

在C#中处理PNG和JPG/JPEG图像时,通常会使用到System.Drawing命名空间(或较新的System.Drawing.Common),以及可能的第三方库如ImageSharp等。从.NET Core 3.0开始,System.Drawing.Common成为了跨平台处理图像的标准方式,但需要注意的是自.NET 6起,微软建议在非Windows平台上使用其他库,因为System.Drawing.Common在Linux和macOS上的实现依赖于GDI+,这可能会带来兼容性问题。

使用System.Drawing.Common处理图像

以下是使用System.Drawing.Common库加载、保存PNG和JPEG图像的基本示例:

加载和保存图像

using System;
using System.Drawing;
using System.Drawing.Imaging;class Program
{static void Main(){// 加载一个PNG或JPG图像using (Image image = Image.FromFile("example.png")){// 保存为PNG格式image.Save("output.png", ImageFormat.Png);// 保存为JPG格式,并设置质量var encoderParams = new EncoderParameters(1);encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, 90L); // 设置JPEG质量为90ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Jpeg);image.Save("output.jpg", jpgEncoder, encoderParams);}}private static ImageCodecInfo GetEncoder(ImageFormat format)
{ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();foreach (ImageCodecInfo codec in codecs){if (codec.FormatID == format.Guid){return codec;}}return null;
}
}

处理透明度

  • PNG:当你处理需要保留透明背景的图像时,可以无损地保存为PNG格式。使用ImageFormat.Png作为保存格式即可。
  • JPEG:由于JPEG不支持透明度,所有透明区域将会被填充为某种颜色(通常是白色)。如果你尝试将具有透明度的PNG图像保存为JPEG格式,必须决定如何处理这些透明部分。
编码器像素格式透明通道背景色
JpegBitmapEncoder不支持透明(Alpha=1)强制不透明未初始化的像素为 黑色 (0,0,0)
PngBitmapEncoder支持透明使用 Pbgra32 等格式未绘制区域 Alpha=0(透明),但显示时背景为白色(取决于查看器)

总之,在C#中处理PNG和JPG/JPEG图像主要涉及到正确使用System.Drawing.Common中的类和方法来加载、修改和保存图像文件。对于更高级的需求,比如复杂的图像处理或在非Windows平台上更好的兼容性,考虑使用如ImageSharp这样的第三方库可能是明智的选择。

在C#中处理PNG图像的透明部分,通常涉及到使用System.DrawingSystem.Drawing.Common命名空间中的类。以下是一些基本的操作方法,包括如何创建带有透明度的图像、如何设置图像区域为透明以及如何保存包含透明度的PNG文件。

创建带有透明背景的图像

当你创建一个新的图像时,可以通过指定像素格式来包含透明度支持:

using System.Drawing;
using System.Drawing.Imaging;// 创建一个32位带有Alpha通道(透明度)的新Bitmap对象
Bitmap bitmap = new Bitmap(100, 100, PixelFormat.Format32bppArgb);// 获取图形上下文
Graphics g = Graphics.FromImage(bitmap);// 设置背景颜色为完全透明
g.Clear(Color.Transparent);

处理现有图像的透明部分

对于已经存在的PNG图像,如果你想要修改其透明度或者将某个颜色替换为透明,可以这样做:

using (Bitmap bitmap = new Bitmap("input.png"))
{for (int x = 0; x < bitmap.Width; x++){for (int y = 0; y < bitmap.Height; y++){Color pixelColor = bitmap.GetPixel(x, y);// 假设我们想将纯绿色变为透明if (pixelColor.R == 0 && pixelColor.G == 255 && pixelColor.B == 0){bitmap.SetPixel(x, y, Color.FromArgb(0)); // 完全透明}}}// 保存结果,注意要保存为PNG以保留透明度bitmap.Save("output.png", ImageFormat.Png);
}

背景默认填充色

JPEG 格式本身并不支持透明度,因此在将包含透明区域的图像保存为 JPEG 时,这些透明区域需要被某种颜色填充。默认情况下,不同的软件和库可能会以黑色或白色来填充这些透明区域,但这并不是由 JPEG 标准本身决定的,而是具体实现的选择。

黑色或白色作为默认填充色

  • 默认行为:当使用某些工具或库(例如你提到的 JpegBitmapEncoder)将具有透明度的图像转换为 JPEG 格式时,透明部分通常会被填充为黑色或者白色。这种选择通常是库或工具开发者所做的一个设计决策,并不是固定的规则。

  • 为什么是黑色或白色?

    • 黑色:一些实现可能选择黑色作为默认填充色,因为这可以避免与浅色背景混合时产生强烈的对比,尤其是在图像编辑和视频处理中。
    • 白色:另一方面,白色有时也被用作默认填充色,特别是在网页设计或其他需要明亮背景的应用场景中。

自定义填充色

对于想要自定义这个填充色(例如设定为黑色或白色,甚至是其他颜色),你需要在将图像编码为 JPEG 之前手动填充透明区域。以下是大致步骤:

  1. 创建一个新的位图,其大小与原图相同,并且背景色为你希望的填充色(比如黑色或白色)。
  2. 将原始图像绘制到这个新的位图上。这样做会覆盖掉新的位图中的相应部分,而任何未被覆盖的部分(即原图中的透明区域)将保留你所选的颜色。
  3. 使用 JpegBitmapEncoder 或类似的工具将这个新生成的位图保存为 JPEG 文件

这种方法允许你在保存 JPEG 文件之前控制如何处理图像的透明区域,包括选择任何你希望的填充颜色。

想将透明区域填充为黑色,然后保存为 JPEG:

// 假设 originalBitmap 是你的原始 BitmapSource
var blackBackgroundBitmap = new RenderTargetBitmap(originalBitmap.PixelWidth, originalBitmap.PixelHeight, 96, 96, PixelFormats.Pbgra32);
DrawingVisual drawingVisual = new DrawingVisual();
using (DrawingContext dc = drawingVisual.RenderOpen())
{// 先画一个黑色背景dc.DrawRectangle(Brushes.Black, null, new Rect(0, 0, originalBitmap.Width, originalBitmap.Height));// 然后绘制你的原始图像dc.DrawImage(originalBitmap, new Rect(0, 0, originalBitmap.Width, originalBitmap.Height));
}
blackBackgroundBitmap.Render(drawingVisual);// 接下来使用 JpegBitmapEncoder 保存 blackBackgroundBitmap
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(blackBackgroundBitmap));
using (var fileStream = new FileStream("output.jpg", FileMode.Create))
{encoder.Save(fileStream);
}

使用白色填充透明区域

如果你想要使用白色来填充透明区域,只需将上面代码中的 Brushes.Black 替换为 Brushes.White

// 绘制一个白色背景代替黑色背景 dc.DrawRectangle(Brushes.White, null, new Rect(0, 0, originalBitmap.Width, originalBitmap.Height));

通过这种方式,你可以根据需要选择任何颜色作为背景色来填充透明区域。只需要更改DrawRectangle方法中使用的画刷(Brush)即可。这样,在最终保存为JPEG格式时,原本透明的部分就会被你选择的颜色所替代。

注意事项

  • PixelFormat:确保使用支持透明度的像素格式(如Format32bppArgb),以便正确处理透明度。
  • 保存格式:由于JPEG不支持透明度,因此当处理需要透明背景的图像时,请使用PNG格式进行保存。
  • 性能考虑GetPixelSetPixel方法对于大量操作来说效率较低。对于性能敏感的应用,可以考虑使用LockBits方法直接访问图像数据,但这要求更复杂的代码处理。

 

jpg、bmp、png图像的位深度分别有多少种?分别表示什么意思?如果操作时需要注意什么?_png 位深度-CSDN博客文章浏览阅读8.5k次,点赞30次,收藏22次。C#语言操作 jpg、bmp、png图像的位深度分别有多少种?分别表示什么意思?如果操作时需要注意什么?_png 位深度 https://blog.csdn.net/wangnaisheng/article/details/137332692C# Bitmap转换为jpg、bmp、png、gif图片_c# bitmap 保存图片jpg-CSDN博客文章浏览阅读4.7k次。该代码示例展示了如何使用C#将Bitmap对象转换为不同格式的图片,包括JPG、BMP、PNG和GIF。通过检查文件后缀并使用ImageFormat和ImageCodecInfo类,程序能保存图片到指定格式,并支持设置JPEG的质量参数。 https://blog.csdn.net/wangnaisheng/article/details/129838880?spm=1011.2415.3001.5331

 

http://www.dtcms.com/a/331551.html

相关文章:

  • Oracle commit之后做了什么
  • 【20-模型诊断调优】
  • BSCI认证对企业的影响,BSCI认证的重要性,BSCI审核的核心内容
  • 信息vs知识:人类学习与AI规则提取
  • 设计模式笔记_行为型_状态模式
  • Spring Boot + Redis Sentinel (一主两从)测试案例
  • Docker pull拉取镜像命令的入门教程
  • 蓝耘元生代上线 Baichuan-M2-32B,医疗推理能力卓越,高效部署,成本超低
  • Varjo XR虚拟现实军用车辆驾驶与操作培训
  • SaltStack部署应用
  • MCP入门:Python开发者的模型上下文协议实战指南
  • VSCode打开新的文件夹之后当前打开的文件夹被覆盖
  • 百度智能云x中科大脑:「城市智能体」如何让城市更会思考
  • 如何启动本机mysql数据库
  • 软件架构需求过程:构建高质量系统的基石
  • C#面试题及详细答案120道(01-10)-- 基础语法与数据类型
  • 【Android】RecyclerView复用CheckBox的异常状态
  • 容器方式安装Prometheus以及Grafana
  • 《疯狂Java讲义(第3版)》学习笔记ch4
  • C# 贪吃蛇游戏
  • js加密逆向
  • Chrome插件开发实战:从零开发高效Chrome插件,提升浏览器生产力
  • 通过 USB 配置闭环驱动器——易格斯igus
  • glTF-教程/glb-教程
  • tlias智能学习辅助系统--Maven 高级-私服介绍与资源上传下载
  • AI硬件小众赛道崛起:垂直场景的价值重构与增长密码。
  • Java高级流
  • 公链开发竞争白热化:如何设计下一代高性能、可扩展的区块链基础设施?
  • 云手机的存储功能怎么样?
  • 一次 Unity ↔ Android 基于 RSA‑OAEP 的互通踩坑记