public static byte [] reduceImg(byte [] imgData, int widthdist, int heightdist) {
ByteArrayOutputStream outputStream = null;
ByteArrayInputStream inputStream = null;
try {
inputStream = new ByteArrayInputStream(imgData);
Image src = javax.imageio.ImageIO.read(inputStream);
//TYPE_INT_ARGB 2
//TYPE_4BYTE_ABGR 6
//TYPE_4BYTE_ABGR_PRE 7
BufferedImage bufferedImage = new BufferedImage(widthdist, heightdist,
BufferedImage.TYPE_4BYTE_ABGR_PRE);
bufferedImage.getGraphics().drawImage(
src.getScaledInstance(widthdist, heightdist,
Image.SCALE_REPLICATE), 0, 0, null);
outputStream = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png",outputStream);
// JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outputStream);
// encoder.encode(bufferedImage);
return outputStream.toByteArray();
} catch (Exception ex) {
logger.error("Reduce user avatar failed!", ex);
return null;
} finally{
if( null != outputStream){
try {
outputStream.close();
} catch (IOException e) {
logger.error("", e);
}
}
if( null != inputStream){
try {
inputStream.close();
} catch (IOException e) {
logger.error("", e);
}
}
}
}
TYPE_INT_ARGB 2
public static final int TYPE_INT_ARGB表示一个图像,它具有合成整数像素的 8 位 RGBA 颜色分量。
该图像具有带 alpha 的 DirectColorModel。认为此图像中的颜色数据没有预乘以 alpha。当使用此类型
作为 BufferedImage 构造方法的 imageType 参数时,所创建的图像与 JDK1.1 和更早期版本中创建的图
像一致。
TYPE_4BYTE_ABGR 6
public static final int TYPE_4BYTE_ABGR表示一个具有 8 位 RGBA 颜色分量的图像,具有用 3 字节存
储的 Blue、Green 和 Red 颜色以及 1 字节的 alpha。该图像具有带 alpha 的 ComponentColorModel。
认为此图像中的颜色数据没有预乘以 alpha。按照每个像素中字节地址从低到高的顺序 A、B、G、R 将字节
数据插入单个字节数组中。
TYPE_4BYTE_ABGR_PRE 7
public static final int TYPE_4BYTE_ABGR_PRE表示一个具有 8 位 RGBA 颜色分量的图像,具有用 3 字节
存储的 Blue、Green 和 Red 颜色以及 1 字节的 alpha。该图像具有带 alpha 的 ComponentColorModel。
认为此图像中的颜色数据已预乘以 alpha。按照每个像素中字节地址从低到高的顺序 A、B、G、R 将字节数据
插入单个字节数组中。
=======================================================
参考JDK中java.awt.AlphaComposite
=======================================================
类实现一些基本的 alpha 合成规则,将源色与目标色组合,在图形和图像中实现混合和透明效果。此类实现的特定规则是 T. Porter 和 T. Duff 合著的 "Compositing Digital Images", SIGGRAPH 84, 253-259 中描述的 12 条基本规则集。本文档的其余部分假定读者熟悉上述论文中概括的定义和概念。
此类扩展了 Porter 和 Duff 定义的方程,包含一个额外的因子。AlphaComposite 类的实例可以包含一个 alpha 值,在将该值用于混合方程之前,可以用它来修改不透明度和每个源像素的覆盖率。
要重点注意的是,Porter 和 Duff 的论文中定义的方程完全是为颜色分量方面的操作定义的,这些颜色分量都要用它们对应的 alpha 分量预乘。因为 ColorModel 和 Raster 类允许以预乘和非预乘的方式存储像素数据,所以在将所有输入数据应用到方程之前,必须将它们标准化为预乘形式,并且在存储像素值之前,可能需要将所有结果都调整回目标所需的形式。
还要注意的是,此类只定义了以纯数学方式组合颜色和 alpha 值的方程。方程的具体应用取决于从数据源中检索数据和将它们存储到其目标中的方式。有关更多信息,请参阅实现警告事项。
Porter 和 Duff 的论文在混合方程的描述中使用了以下因子:
因子 定义
As 源像素的 alpha 分量
Cs 源像素的预乘形式的颜色分量
Ad 目标像素的 alpha 分量
Cd 目标像素的预乘形式的颜色分量
Fs 用于输出的源像素的分数值
Fd 用于输出的目标像素的分数值
Ar 结果 alpha 分量
Cr 结果预乘形式的颜色分量
使用这些因子,Porter 和 Duff 定义了 12 种选择混合因子 Fs 和 Fd 的方法,从而产生了 12 种令人满意的可视效果。在对 12 个指定可视效果的静态字段的描述中,给出了具有确定 Fs 和 Fd 值的方程。例如,对 SRC_OVER 的描述指定了 Fs = 1 和 Fd = (1-As)。一旦已知一组确定混合因子的方程,就可以使用以下方程组将它们应用于每个像素以生成结果:
Fs = f(Ad)
Fd = f(As)
Ar = As*Fs + Ad*Fd
Cr = Cs*Fs + Cd*Fd在我们对 Porter 和 Duff 论文混合方程的扩展中,用到了以下因子:
因子 定义
Csr 源像素的原始颜色分量之一
Cdr 目标像素的原始颜色分量之一
Aac 取自 AlphaComposite 实例的“额外的”alpha 分量
Asr 源像素的原始 alpha 分量
Adr 目标像素的原始 alpha 分量
Adf 目标中存储的最终 alpha 分量
Cdf 目标中存储的最终原始颜色分量
准备输入
AlphaComposite 类定义一个应用于源 alpha 的额外 alpha 值。应用此值就好像首先将隐式的 SRC_IN 规则应用于源像素(通过将原始源 alpha 和原始源色乘以 AlphaComposite 中的 alpha 值获得),而不是应用于具有指定 alpha 值的像素。这产生了以下方程,该方程生成 Porter 和 Duff 的混合方程中使用的 alpha 值:
As = Asr * Aac 所有这些原始源色分量都必须乘以 AlphaComposite 实例中的 alpha 值。此外,如果源色分量不是预乘形式的,那么还需要将颜色分量乘以源 alpha 值。因此,用来生成 Porter 和 Duff 方程源色分量的方程取决于源像素是否已经被预乘:
Cs = Csr * Asr * Aac (如果源像素没有被预乘)
Cs = Csr * Aac (如果源像素被预乘) 无需对目标 alpha 进行调整:
Ad = Adr 仅当目标色分量不是预乘形式时,才需要对它们进行调整:
Cd = Cdr * Ad (如果目标色分量没有被预乘)
Cd = Cdr (如果目标色分量被预乘) 应用混合方程
调整后的 As、Ad、Cs 和 Cd 将用于标准的 Porter 和 Duff 方程,以计算混合因子 Fs 和 Fd,然后计算得到的预乘分量 Ar 和 Cr。
准备结果
仅当结果要存储回保存未预乘数据的目标缓冲区时,才需要使用以下方程调整结果:
Adf = Ar
Cdf = Cr (如果目标数据被预乘)
Cdf = Cr / Ar (如果目标数据没有被预乘) 注意,在所得 alpha 为零时除法是不明确的,所以在这种情况下会忽略除法以避免“除以零”的情况,此时颜色分量都将为零。
性能考虑事项
出于性能方面的原因,传递给 CompositeContext 对象(由 AlphaComposite 类创建) compose 方法的 Raster 对象最好有预乘数据。不过,如果源 Raster 或目标 Raster 没有被预乘,那么可以在合成操作之前或之后执行适当的转换。
实现警告事项
许多源图像,比如 BufferedImage 类中列出的一些不透明图像类型,没有为它们的像素存储 alpha 值。这类源图像为它们所有的像素提供了值为 1.0 的 alpha 值。
许多目标也没有地方存储 alpha 值(这些值是此类执行混合计算的结果)。这类目标会隐式丢弃此类产生的 alpha 值。建议这类目标将它们存储的颜色值作为未预乘的值对待,并在存储颜色值和丢弃 alpha 值之前,将得到的颜色值除以得到的 alpha 值。
结果的精度取决于将像素存储到目标中的方式。对于一连串十二种合成操作中的少数操作,将为每种颜色和 alpha 分量提供至少 8 个存储位的图像格式作为目标无论如何都应该足够了。在舍入误差支配结果之前,为每个分量提供少于 8 个存储位的图像格式仅限用于一或两个合成操作。对于任何半透明混合的类型而言,不单独存储颜色分量的图像格式不是一个好的候选方式。例如,不应将 BufferedImage.TYPE_BYTE_INDEXED 用作混合操作的目标,因为需要从限定的调色板选择像素,以匹配混合方程的结果,所以每个操作都可能引入大量错误。
几乎所有的格式都将像素存储为离散整数,而不是将它们存储为上述方程中使用的浮点值。该实现可以将整数像素值缩放成范围在 0.0 到 1.0 之间的浮点值,或者使用稍作修改的方程,完全在整数域内操作,从而生成与上述方程类似的结果。
通常,整数值与浮点值存在某种相关性:整数 0 等于浮点值 0.0,整数 2^n-1(其中 n 是表示形式中的位数)等于 1.0。对于 8 位的表示形式,这意味着 0x00 表示 0.0,0xff 表示 1.0。
内部实现可能近似于某些方程,它们也可以消除一些步骤,以避免不必要的操作。例如,可以考虑一个离散整数图像,它带有未预乘的 alpha 值,并为存储每个分量使用了 8 个位。接近透明的暗红色存储的值可能是:
(A, R, G, B) = (0x01, 0xb0, 0x00, 0x00)如果正在使用整数运算,并且此值在 SRC 模式下没有与任何 alpha 值合成,则该运算将指示此运算的结果为(整数格式):
(A, R, G, B) = (0x01, 0x01, 0x00, 0x00)注意中间的值,它总是以已预乘的形式出现,并且只允许整数 red 分量为 0x00 或 0x01。当试图将此结果存储回未预乘的目标中时,用 alpha 值相除之后,对于未预乘的 red 值,可进行的选择很少。在这种情况下,在整数空间内执行运算(没有快捷方式)的实现最后可能提供以下最终像素值:
(A, R, G, B) = (0x01, 0xff, 0x00, 0x00)(注意,0x01 除以 0x01 得到的是 1.0,等于 8 位存储格式的值 0xff。)
另一方面,使用浮点运算的实现可以生成更精确的结果,并以返回原始像素值结束,该值有可能带有少量的舍入误差。或者,使用整数运算的实现可能决定是否可以将未涉及的像素传输给目标,完全避免所有运算。因为如果在浮点空间内执行运算,方程可简单归结为颜色值上的一个虚拟 NOP。
这些实现都试图遵守相同的方程,但使用经过权衡的不同整数和浮点运算,并使用部分的或全部的方程。为了说明这些不同之处,可能最好只期望获得已预乘形式的结果,以在实现和图像格式之间进行匹配。在这种情况下,以预乘形式表示的两种答案将等同于:
(A, R, G, B) = (0x01, 0x01, 0x00, 0x00)并且它们将是完全匹配的。
因为那些通过简化方程使计算更有效的技术,在非预乘的目标上遇到值为 0.0 的结果 alpha 值时,一些实现的执行可能会有所不同。注意,如果分母 (alpha) 为 0,则在 SRC 规则下移除除以 alpha 这一简化操作技术上是不合法的。但是,因为在以预乘形式查看时只期望结果是精确的,所以,结果为 0 的 alpha 值呈现的实质上是所得到的不相关颜色分量,因此,在这种情况下,具体的行为应该是无法预料的。
分享到:
相关推荐
2. **图像叠加**:当合成两张图片时,通常会根据底层图片的Alpha值和顶层图片的颜色进行计算,生成新的像素值。这个过程可能涉及到“Alpha混合”算法,如Porter-Duff算法或更简单的乘法混合。 3. **图像裁剪与缩放*...
在Qt库中,图片合成是一项重要的图像处理功能,它允许开发者将多张图片按照特定的模式融合在一起,创建出新的视觉效果。这个过程通常涉及到Qt的`QPainter`类及其枚举类型`QPainter::CompositionMode`。在这个场景中...
5. 透明度处理:PNG图像支持alpha通道,即透明度信息。在合成时,需要考虑源图像的透明度,正确地将不透明部分与目标图像结合。 6. 输出合成图像:完成合成后,你需要将结果保存为新的PNG图像文件。这里同样需要...
在C#编程环境中,图片合成是一项常见的图像处理任务,它涉及到多个图像操作,如合并、叠加、裁剪、旋转等。这个"**C#实现图片合成经典源码.rar**"文件很可能包含了一些实用的示例代码,用于演示如何在C#中进行图片...
然而,处理带有透明背景的PNG图片时,可能会遇到一个常见的问题:压缩后的图片透明部分变为黑色。这个问题通常是由于不正确的图像类型设置或者在处理透明度时的不当操作造成的。本文将深入探讨如何解决Java压缩图片...
这可能涉及到透明度处理,即Alpha通道的处理,因为PNG格式支持透明。在易语言中,这通常需要对每个像素进行操作,计算其颜色值与透明度,然后将结果写入新的图像缓冲区。 最后,合成后的图片会被直接输出为字节集。...
4. **透明度处理**:在某些情况下,一个图像可能具有透明度信息(即Alpha通道),需要在合成时考虑这一因素,使得图像边缘更加自然。 5. **滤波与抗锯齿**:为了提高合成图像的质量,可能会应用平滑滤波来减少噪声...
Alpha通道特别重要,因为它提供了不规则透明度的支持,使得PNG图像可以实现半透明效果,这在合成序列图时尤为关键。例如,在制作动画时,每一帧可能包含不同级别的透明度,通过合成这些PNG序列,可以创建出平滑的...
压缩包子文件“图片合成工具”可能包含了可执行文件(如Windows下的.exe或Linux下的可执行脚本)以及源代码文件。源代码文件通常以`.erl`为扩展名,代表Erlang语言的源代码。用户可以通过阅读和分析这些源代码,学习...
实现这一功能可能需要用到图像合成技术,如Alpha混合,以及坐标定位和透明度控制等。 最后,批量更改格式则涉及到图像文件的转换。不同的格式有不同的适用场景,如JPEG适合连续色调的彩色照片,而PNG适合包含透明度...
1. **透明性**:PNG支持24位彩色图像以及一个额外的透明通道(即Alpha通道),允许用户设置图像的不透明度,实现半透明或完全透明的效果,这对于网页设计和图标制作尤其有用。 2. **无损压缩**:PNG采用无损压缩算法...
PNG(Portable Network Graphics)是一种无损压缩的位图格式,常用于网页设计、图形编辑和图标制作等场景,因为它支持透明度,并且能保持图像质量不变。在某些情况下,如创建动画或复杂的图像组合时,可能需要将多个...
在图像处理领域,有时我们需要将具有固定背景色的图片转换为具有透明背景的图片,以实现更好的视觉效果或便于在不同背景下使用。本教程聚焦于使用OpenCV库,特别是通过Python编程语言,来实现这一目标。我们将探讨...
这个过程需要考虑像素的混合规则,例如普通的颜色叠加或基于Alpha通道的混合。 6. **压缩并写入新PNG**:使用libpng库和zlib进行编码和压缩,将合并后的大图片写入新的PNG文件。编码过程会按照PNG文件格式标准重新...
RGB16、RGB24和RGB32分别代表了16位、24位和32位的色彩深度,其中32位通常包含额外的透明度通道(Alpha通道)。位深度越高,表示颜色的精度越高,图像色彩更丰富。 对于原始无压缩的图片和视频数据,直接查看往往...
在PNG图片合成中,可能需要理解PNG的Alpha通道,用于控制图像的透明度。 3. **图像合成**:学习如何将多个PNG图片合成为一个新的图像。这可能涉及到坐标系统、图像裁剪、缩放、旋转等操作,以及如何处理重叠部分的...
Png(Portable Network Graphics)是一种无损压缩的位图格式,提供透明度(Alpha通道)支持,同时也支持24位真彩色和8位灰度图像。与JPEG等有损压缩格式相比,Png在保存图像细节时不会出现像素损失,因此特别适合...
- 图像合成:如 alpha 混合,将两个图像按照一定规则结合在一起。 5. 类库设计: - 可能包含一个或多个类,如`Image`或`PixelArray`,提供对图像数据的操作接口。 - 使用面向对象的设计模式,如封装图像数据、...
在JPEG图片上添加水印,主要涉及图像处理技术,包括像素操作、透明度处理和合成技术。 实现JPEG图片叠加水印,通常需要编程语言支持,如Python、Java或C++等,结合图像处理库,例如Python的PIL(Pillow)库或Java的...