在 Java 和 PHP 中获取 RGB 有不同的结果
Get RGB in Java and PHP have different result
我想获取每个像素的 RGB 代码。作为示例,我以像素(0,0)(左角)为例。 我加载 JPEG 图像,然后存储在 Java 中的位图对象中。对于实验,我附加了图像,例如:
我采用 PHP 和 Java 的 RGB。这里的代码:
Java(rgbImage 是从 JPEG 文件加载的 Bitmap 对象):
int width = rgbImage.getWidth();
int height = rgbImage.getHeight();
for (int x = 0; x < rgbImage.getWidth(); x++){
for (int y = 0; y < rgbImage.getHeight(); y++) {
int pixel = rgbImage.getPixel(x, y);
double red = Color.red(pixel);
double green = Color.green(pixel);
double blue = Color.blue(pixel);
if(x == 0 && y == 0){
System.out.println("red : "+red+" green : "+green+" blue : "+blue);
}
PHP :
$rgbImage = imagecreatefromjpeg("$path");
$width = imagesx($rgbImage);
$height = imagesy($rgbImage);
for($x = 0 ; $x < $width ; $x++){
for($y = 0 ; $y < $height ; $y++){
$rgb = imagecolorat($rgbImage, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
if($x == 0 && $y == 0){
echo("r : $r , g : $g, b : $b <br/>");
}
}
}
结果都是:
JAVA : I/System.out: 红色 : 91.0 绿色 : 91.0 蓝色 : 101.0
PHP: r: 93, g: 91, b: 102
主要问题是:
为什么同一张图片,上面两种方法给出的结果不同?
BMP 不同于 JPEG。
JPEG 是压缩文件,而 BMP 是精确的未压缩文件(大部分)。当您在 PHP 中创建 JPEG 时,图像会被压缩并丢失一些信息,人眼很难注意到差异。在 Java 中,您使用未使用 JPEG 压缩的原始位图。因此,正如您所注意到的,两个结果图像可能不同。
阅读 here or here 了解这些格式与其他格式之间的差异。
JPEG 使用基于 on the discrete cosine transform (DCT) 的特定压缩。
此压缩将使用数学公式根据像素面积减小信息的大小。这将导致需要在某些时候四舍五入的浮动值。当然,反之亦然,要从 JPEG 重建位图,需要一些数学运算,基于如何实现将导致差异,因为可能会以不同的方式舍入某些值。
所以基本上,你有一幅画(bmp文件),你想减少它的细节(信息数量=文件大小),为此,你可以用水稀释油漆,这幅画远看还是很漂亮的。但是一旦你这样做了,你将看到的细节将取决于你想象它们的大脑。每个大脑(重新创建位图的算法)都会看到一幅略有不同的画。
我想获取每个像素的 RGB 代码。作为示例,我以像素(0,0)(左角)为例。 我加载 JPEG 图像,然后存储在 Java 中的位图对象中。对于实验,我附加了图像,例如:
我采用 PHP 和 Java 的 RGB。这里的代码:
Java(rgbImage 是从 JPEG 文件加载的 Bitmap 对象):
int width = rgbImage.getWidth();
int height = rgbImage.getHeight();
for (int x = 0; x < rgbImage.getWidth(); x++){
for (int y = 0; y < rgbImage.getHeight(); y++) {
int pixel = rgbImage.getPixel(x, y);
double red = Color.red(pixel);
double green = Color.green(pixel);
double blue = Color.blue(pixel);
if(x == 0 && y == 0){
System.out.println("red : "+red+" green : "+green+" blue : "+blue);
}
PHP :
$rgbImage = imagecreatefromjpeg("$path");
$width = imagesx($rgbImage);
$height = imagesy($rgbImage);
for($x = 0 ; $x < $width ; $x++){
for($y = 0 ; $y < $height ; $y++){
$rgb = imagecolorat($rgbImage, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
if($x == 0 && $y == 0){
echo("r : $r , g : $g, b : $b <br/>");
}
}
}
结果都是:
JAVA : I/System.out: 红色 : 91.0 绿色 : 91.0 蓝色 : 101.0
PHP: r: 93, g: 91, b: 102
主要问题是:
为什么同一张图片,上面两种方法给出的结果不同?
BMP 不同于 JPEG。
JPEG 是压缩文件,而 BMP 是精确的未压缩文件(大部分)。当您在 PHP 中创建 JPEG 时,图像会被压缩并丢失一些信息,人眼很难注意到差异。在 Java 中,您使用未使用 JPEG 压缩的原始位图。因此,正如您所注意到的,两个结果图像可能不同。
阅读 here or here 了解这些格式与其他格式之间的差异。
JPEG 使用基于 on the discrete cosine transform (DCT) 的特定压缩。
此压缩将使用数学公式根据像素面积减小信息的大小。这将导致需要在某些时候四舍五入的浮动值。当然,反之亦然,要从 JPEG 重建位图,需要一些数学运算,基于如何实现将导致差异,因为可能会以不同的方式舍入某些值。
所以基本上,你有一幅画(bmp文件),你想减少它的细节(信息数量=文件大小),为此,你可以用水稀释油漆,这幅画远看还是很漂亮的。但是一旦你这样做了,你将看到的细节将取决于你想象它们的大脑。每个大脑(重新创建位图的算法)都会看到一幅略有不同的画。