Java/Processing-带环绕边的缩放图像矩阵
我一直想知道如何在Java或Processing中高效地实现下面的图像缩放过程。向外缩放时,图像的边界环绕屏幕边缘。我希望在运行时将其应用于处理中的像素()数组。(为了保持这种处理不可知,Pixels()就是一种以数组形式返回当前屏幕上所有像素的方法) (请注意,此示例是使用jit.rota模块在MaxMsp/Jitter中创建的,该模块似乎使用了非常高效的实现)Java/Processing-带环绕边的缩放图像矩阵,java,image-processing,processing,image-scaling,max-msp-jitter,Java,Image Processing,Processing,Image Scaling,Max Msp Jitter,我一直想知道如何在Java或Processing中高效地实现下面的图像缩放过程。向外缩放时,图像的边界环绕屏幕边缘。我希望在运行时将其应用于处理中的像素()数组。(为了保持这种处理不可知,Pixels()就是一种以数组形式返回当前屏幕上所有像素的方法) (请注意,此示例是使用jit.rota模块在MaxMsp/Jitter中创建的,该模块似乎使用了非常高效的实现) 有人能帮我开始吗?我想这一定是缩小图像尺寸和创建其相邻副本的组合——但这听起来不是很有效。上面的示例在具有最极端设置的视频上也能
有人能帮我开始吗?我想这一定是缩小图像尺寸和创建其相邻副本的组合——但这听起来不是很有效。上面的示例在具有最极端设置的视频上也能完美运行。我认为最快的一个选项是使用基本片段着色器 幸运的是,通过文件>示例>主题>着色器>无限瓷砖 我无法有效地提供一个良好的从开始到结束的指南,但是 如果你从零开始,有一个详尽的答案 你需要什么的大致要点:
- 着色器是在GPU上运行速度非常快且并行的程序,分为两部分:顶点着色器(主要处理3d几何体)和片段着色器(主要处理“片段”(即将成为屏幕上的像素)。您将需要使用片段着色器
- 这种语言叫做GLSL,有点不同(类型更少,语法更严格,更简单),但不是完全陌生(类似于C类型的声明变量、函数、条件、循环等)
- 如果要使GLSL程序中的变量在处理过程中可访问,请使用关键字
uniform
- 用于包裹边
- 要缩放图像并将其包裹,需要缩放纹理采样坐标:
//---------------------------------------------------------
// Display endless moving background using a tile texture.
// Contributed by martiSteiger
//---------------------------------------------------------
uniform float time;
uniform vec2 resolution;
uniform sampler2D tileImage;
#define TILES_COUNT_X 4.0
void main() {
vec2 pos = gl_FragCoord.xy - vec2(4.0 * time);
vec2 p = (resolution - TILES_COUNT_X * pos) / resolution.x;
vec3 col = texture2D (tileImage, p).xyz;
gl_FragColor = vec4 (col, 1.0);
}
您可以简化这一点,因为您不需要滚动。此外,您不需要进行减法和乘法(-TILES\u COUNT\u X*pos
),只需进行乘法即可:
//---------------------------------------------------------
// Display endless moving background using a tile texture.
// Contributed by martiSteiger
//---------------------------------------------------------
uniform float scale;
uniform vec2 resolution;
uniform sampler2D tileImage;
void main() {
vec2 pos = gl_FragCoord.xy * vec2(scale);
vec2 p = (resolution - pos) / resolution.x;
vec3 col = texture2D (tileImage, p).xyz;
gl_FragColor = vec4 (col, 1.0);
}
请注意,我已将时间
变量重新调整为比例
,因此访问此统一变量的处理代码也必须更改:
//-------------------------------------------------------------
// Display endless moving background using a tile texture.
// Contributed by martiSteiger
//-------------------------------------------------------------
PImage tileTexture;
PShader tileShader;
void setup() {
size(640, 480, P2D);
textureWrap(REPEAT);
tileTexture = loadImage("penrose.jpg");
loadTileShader();
}
void loadTileShader() {
tileShader = loadShader("scroller.glsl");
tileShader.set("resolution", float(width), float(height));
tileShader.set("tileImage", tileTexture);
}
void draw() {
tileShader.set("scale", map(mouseX,0,width,-3.0,3.0));
shader(tileShader);
rect(0, 0, width, height);
}
移动鼠标以更改比例:
更新您可以使用非常类似的着色器:我确实提出了一个解决方案,但下一步将实施George的方法,因为使用着色器的速度差异似乎是值得的
public void scalePixels(double wRatio,double hRatio, PGraphics viewPort) {
viewPort.loadPixels();
int[] PixelsArrayNew = viewPort.pixels.clone();
double x_ratio = wRatio ;
double y_ratio = hRatio ;
double px, py ;
for (int i=0;i<viewPort.height;i++) {
for (int j=0;j<viewPort.width;j++) {
px = Math.floor(j%(wRatio*viewPort.width)/x_ratio) ;
py = Math.floor(i%(hRatio*viewPort.height)/y_ratio) ;
viewPort.pixels[(int)(i*viewPort.width)+j] = PixelsArrayNew[(int)((py*viewPort.width)+px)] ;
}
}
viewPort.updatePixels();
}
public void比例像素(双圈、双圈、PGraphics视口){
loadPixels();
int[]PixelsArrayNew=viewPort.pixels.clone();
双倍x_比率=wRatio;
双y_比=hRatio;
双px,py;
因为(inti=0;我已经试过了吗?)忘记了这不是你的工厂