双线性插值字节翻转Java
所以我一直在做一个3d软件渲染器,需要一个双线性插值方法。为了提高速度,我正在使用一个3字节的BGR光栅,我不知道我的代码在功能上与我直接访问图像本身而拼凑起来的代码有什么不同。在得到结果之前,我将首先列出代码双线性插值字节翻转Java,java,casting,byte,raster,bilinear-interpolation,Java,Casting,Byte,Raster,Bilinear Interpolation,所以我一直在做一个3d软件渲染器,需要一个双线性插值方法。为了提高速度,我正在使用一个3字节的BGR光栅,我不知道我的代码在功能上与我直接访问图像本身而拼凑起来的代码有什么不同。在得到结果之前,我将首先列出代码 float lerp(float x1, float x2, float a) { return x1 * (1 - a) + x2 * a; } 基本线性插值算法 void berp(float sourceX, float sourceY, int destPos, byt
float lerp(float x1, float x2, float a) {
return x1 * (1 - a) + x2 * a;
}
基本线性插值算法
void berp(float sourceX, float sourceY, int destPos, byte[] source, byte[] dest, int sourceWidth) {
float ax = sourceX - 0.5f;
float bx = sourceX + 0.5f;
float xa = ax - (int) (ax);
float ay = sourceY - 0.5f;
float by = sourceY + 0.5f;
float ya = ay - (int) (ay);
int pos1 = (((int) ay) * sourceWidth + ((int) ax)) * 3;
int pos2 = (((int) ay) * sourceWidth + ((int) bx)) * 3;
int pos3 = (((int) by) * sourceWidth + ((int) ax)) * 3;
int pos4 = (((int) by) * sourceWidth + ((int) bx)) * 3;
只需设置它,使pos1到pos4在源阵列中与给定坐标(sourceX和sourceY)最近的4个像素的位置。xa和ya分别是从坐标系到像素中心到顶部和像素到左侧的距离,因此基本上就是从每个像素采样多少
dest[destPos] = (byte) lerp(lerp(source[pos1], source[pos2], xa), lerp(source[pos3], source[pos4], xa), ya);
dest[destPos + 1] = (byte) lerp(lerp(source[pos1 + 1], source[pos2 + 1], xa), lerp(source[pos3 + 1], source[pos4 + 1], xa), ya);
dest[destPos + 2] = (byte) lerp(lerp(source[pos1 + 2], source[pos2 + 2], xa), lerp(source[pos3 + 2], source[pos4 + 2], xa), ya);
}
这里我使用xa在rgb1和rgb2之间插值,然后是rgb3和rgb4。然后我得到这些结果,并使用ya在它们之间进行插值。重复绿色和红色,它应该变成金色
除:
我相信你看到我的困境了
在这一点上,任何帮助都是受欢迎的,我已经尝试了几个小时,但没有任何效果,看起来它是浮动字节转换的翻滚,但我真的不知道如何给出lerp将只给出x1和x2之间的值,并且只有字节进入,所以
*
*
*
*
*
我突然想到,添加生成正确图像的代码可能会有所帮助。有些名称和内容可能不同,但要点就在这里:)
private int getColorBilinear(浮点x、浮点y、缓冲图像s){
浮动nx=x-0.5f;
浮点xa=nx-(int)(nx);
浮动ny=y-0.5f;
浮动ya=ny-(整数)(ny);
int rgb1=s.getRGB((int)(x-0.5),(int)(y-0.5));
int rgb2=s.getRGB((int)(x+0.5),(int)(y-0.5));
int rgb3=s.getRGB((int)(x-0.5),(int)(y+0.5));
int rgb4=s.getRGB((int)(x+0.5),(int)(y+0.5));
返回(int)(插值(
内插((rgb1>>16)和0x000000FF),(rgb2>>16)和0x000000FF),xa,
内插((rgb3>>16)和0x000000FF),(rgb4>>16)和0x000000FF),xa,
ya)>8)和0x000000FF),((rgb2>>8)和0x000000FF),xa),
内插((rgb3>>8)和0x000000FF),(rgb4>>8)和0x000000FF),xa,
实际的过程是这样的:
- 像素值作为无符号字节进行采样
- 对字节(假定为有符号)进行插值
- 插值在目标图像中用作无符号字节
现在令人震惊的是,这实际上适用于大多数情况。当一个源值高于127,另一个低于127时,问题就会出现。例如,插值方法将(129125)视为(-127125)解决这个问题的一种方法是先转换成int,然后再进行插值;下面给出了它的实现
float lerp(byte x1, byte x2, float a) {
return unsignedByteToInt(x1) * (1 - a) + unsignedByteToInt(x2) * a;
}
int unsignedByteToInt(byte x) {return (((int) x) + 255) % 255;}
float lerp(byte x1, byte x2, float a) {
return unsignedByteToInt(x1) * (1 - a) + unsignedByteToInt(x2) * a;
}
int unsignedByteToInt(byte x) {return (((int) x) + 255) % 255;}