绘图图像在处理中抽动
Drawing Images twitching in processing
在此草图中,它水平绘制了一系列对象。每个对象的 x 位置取决于其左侧的对象。此外,当对象不在屏幕上时,它也不会绘制。但是,当我移动时,物体会抽动。我真的不知道为什么,可能是处理的加载图像需要一些时间所以有轻微的延迟?我仅通过绘制矩形 (rect()) 对此进行了测试,但问题并未发生。
以下是使用相同算法绘制从互联网加载的图像的代码:(草图加载可能需要一段时间,因为它正在从不同的网站检索图像)运行之后草图,使用左右箭头键左右移动。使用向上和向下箭头改变移动速度。
PImage backgroundImage;
PFont font;
int x = 0;
int xoffset = 0;
int deltax = 5;
float scale = 512/30;
float deltascale = 0.02;
ArrayList<Object> ObjectList;
class Object {
String name;
float diameter;
String unit;
String sprite;
PImage img;
int wid;
int hei;
int xpos;
Object(String Oname, float Odiameter, String Ounit, String Oimg) {
name = Oname;
diameter = Odiameter;
unit = Ounit;
img = loadImage(Oimg);
sprite = Oimg;
//img = loadImage(Oimg);
wid = img.width;
hei = img.height;
}
}
void setup() {
size(1500, 800);
frameRate(200);
fill(255,255,255);
textSize(32);
textAlign(CENTER, CENTER);
text("Images are loading (this may take a while)",700,400);
ObjectList = new ArrayList();
readObjects();
}
void addObject(String Aname, float Adiameter, String Aunit, String Aimg) {
ObjectList.add(new Object(Aname, Adiameter, Aunit, Aimg));
}
void readObjects() {
addObject("RED", 30, "m", "https://s-media-cache-ak0.pinimg.com/736x/8f/1b/cc/8f1bcc72c81d1e9370597f7239ee476a.jpg");
//addObject("ORANGE", 60, "m", "http://6iee.com/data/uploads/36/489075.jpg");
addObject("YELLOW", 70, "m", "https://i.stack.imgur.com/aez1V.jpg");
addObject("GREEN", 100, "m", "http://space-facts.com/wp-content/uploads/mars.jpg");
addObject("PURPLE", 105, "m", "http://space-facts.com/wp-content/uploads/jupiter.png");
addObject("PINK", 110, "m", "https://vignette1.wikia.nocookie.net/starwars/images/4/4a/Alderaan.jpg");
addObject("BROWN", 150, "m", "https://cdn.pixabay.com/photo/2013/07/12/16/33/venus-151142_960_720.png");
addObject("GRAY", 180, "m", "http://www.lpi.usra.edu/lpi_40th/images/1989/neptune.jpg");
//addObject("WHITE", 200, "m", "http://www.clipartkid.com/images/19/log-in-sign-up-upload-clipart-Dpr48a-clipart.png");
addObject("INDIGO", 300, "m", "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/Sun_in_February.jpg/155px-Sun_in_February.jpg");
addObject("SKYBLUE", 301, "m", "https://upload.wikimedia.org/wikipedia/commons/e/ea/Uranus_(Edited).jpg");
addObject("BLUE", 1000, "m", "https://vignette2.wikia.nocookie.net/heman/images/3/36/Earth.jpg");
}
void draw() {
fill(0,0,0);
rect(0, 0, 1500, 800);
int x = 0 + xoffset;
for ( Object drawObject : ObjectList ) {
float dia = drawObject.diameter;
if (x+drawObject.img.width >= 0 && x <= 1500) {
//checks if image is too small to be drawn
int drawWidth = int(scale * dia);
int drawHeight = int(drawWidth * drawObject.hei / drawObject.wid);
if (drawWidth > 0 && drawHeight > 0) {
drawObject.img.resize(drawWidth, drawHeight);
image(drawObject.img, x, 400-(drawObject.img.height/2));
//calculates font size relative to object's current size
int textSize;
//checks if the name or diameter is longer, then uses the longer one for calculation
fill(255,255,255);
if (drawObject.name.length() < str(drawObject.diameter).length()) {
textSize = int(drawObject.img.width/str(drawObject.diameter).length());
} else {
textSize = int(drawObject.img.width/drawObject.name.length());
}
if (textSize > 0) {
textSize(textSize);
float texty = 418+(drawObject.img.height/2);
if (texty < (418+(drawObject.img.height/2))) {
texty = 418;
}
text(drawObject.name, x+(drawObject.img.width/2), texty);
text(drawObject.diameter+drawObject.unit, x+(drawObject.img.width/2), texty+textSize);
}
}
drawObject.xpos = x;
x += (drawObject.img.width*0.08 + drawObject.img.width);
}
//display deltax
textSize(32);
text(str(deltax), 1450, 10);
text(str(deltascale), 1450, 50);
println(str(scale));
}
}
void mouseWheel(MouseEvent event) {
float e = event.getCount();
if (e < 0) {
scale *= (1 + deltascale);
} else if (e > 0) {
scale *= (1 - deltascale) ;
}
}
void keyPressed() {
if (key == CODED) {
if (keyCode == LEFT) {
xoffset += deltax;
} else if (keyCode == RIGHT) {
xoffset -= deltax;
} else if (keyCode == UP) {
deltax += 5;
} else if (keyCode == DOWN) {
deltax -= 5;
}
}
if (key == 'r') {
//reloadObjects();
} else if (key == 'q') {
deltascale += 0.02;
} else if (key == 'a') {
deltascale -= 0.02;
}
if (deltax < 0) {
deltax = 0;
} else if (deltascale < 0) {
deltascale = 0;
}
}
以下原始代码将无法运行,因为它使用了只有我拥有的图像。
我希望有人能帮助我解决这个错误,或者帮助我改进我的算法。
编辑:代码现在可以验证并显示我遇到的问题
好吧,我注意到只要您的其中一张图片即将离开屏幕的左边缘,图像就会跳动。看起来您可能会在每个图像离开屏幕时以不同方式计算 x 位置。尝试摆脱你的 if (x+drawObject.img.width >= 0 && x <= 1500)
测试(暂时将其注释掉),但将代码保留在 if
.
中
几点:
- 绝对不要创建自己的对象class(正如 Kevin Workman 所说)
- 当您调用
img.resize()
时,您正在对图像数据重新采样,这会随着时间的推移导致质量下降。最好只对 image()
函数使用 width, height
参数(或使用 scale()
转换函数——但这可能更令人困惑)。然后在其余的绘图代码中使用 drawWidth/Height
而不是 img.width/height
。
- 如果你想将图像居中,只需使用
imageMode(CENTER)
而不是自己计算 - 特别是因为看起来你正在使用 'magic number' 400
- 尽量不要使用原始数字作为您的屏幕尺寸 - 而是使用
width
和 height
全局变量 - 当您更改屏幕尺寸时,它会让您的生活更轻松。
在此草图中,它水平绘制了一系列对象。每个对象的 x 位置取决于其左侧的对象。此外,当对象不在屏幕上时,它也不会绘制。但是,当我移动时,物体会抽动。我真的不知道为什么,可能是处理的加载图像需要一些时间所以有轻微的延迟?我仅通过绘制矩形 (rect()) 对此进行了测试,但问题并未发生。
以下是使用相同算法绘制从互联网加载的图像的代码:(草图加载可能需要一段时间,因为它正在从不同的网站检索图像)运行之后草图,使用左右箭头键左右移动。使用向上和向下箭头改变移动速度。
PImage backgroundImage;
PFont font;
int x = 0;
int xoffset = 0;
int deltax = 5;
float scale = 512/30;
float deltascale = 0.02;
ArrayList<Object> ObjectList;
class Object {
String name;
float diameter;
String unit;
String sprite;
PImage img;
int wid;
int hei;
int xpos;
Object(String Oname, float Odiameter, String Ounit, String Oimg) {
name = Oname;
diameter = Odiameter;
unit = Ounit;
img = loadImage(Oimg);
sprite = Oimg;
//img = loadImage(Oimg);
wid = img.width;
hei = img.height;
}
}
void setup() {
size(1500, 800);
frameRate(200);
fill(255,255,255);
textSize(32);
textAlign(CENTER, CENTER);
text("Images are loading (this may take a while)",700,400);
ObjectList = new ArrayList();
readObjects();
}
void addObject(String Aname, float Adiameter, String Aunit, String Aimg) {
ObjectList.add(new Object(Aname, Adiameter, Aunit, Aimg));
}
void readObjects() {
addObject("RED", 30, "m", "https://s-media-cache-ak0.pinimg.com/736x/8f/1b/cc/8f1bcc72c81d1e9370597f7239ee476a.jpg");
//addObject("ORANGE", 60, "m", "http://6iee.com/data/uploads/36/489075.jpg");
addObject("YELLOW", 70, "m", "https://i.stack.imgur.com/aez1V.jpg");
addObject("GREEN", 100, "m", "http://space-facts.com/wp-content/uploads/mars.jpg");
addObject("PURPLE", 105, "m", "http://space-facts.com/wp-content/uploads/jupiter.png");
addObject("PINK", 110, "m", "https://vignette1.wikia.nocookie.net/starwars/images/4/4a/Alderaan.jpg");
addObject("BROWN", 150, "m", "https://cdn.pixabay.com/photo/2013/07/12/16/33/venus-151142_960_720.png");
addObject("GRAY", 180, "m", "http://www.lpi.usra.edu/lpi_40th/images/1989/neptune.jpg");
//addObject("WHITE", 200, "m", "http://www.clipartkid.com/images/19/log-in-sign-up-upload-clipart-Dpr48a-clipart.png");
addObject("INDIGO", 300, "m", "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/Sun_in_February.jpg/155px-Sun_in_February.jpg");
addObject("SKYBLUE", 301, "m", "https://upload.wikimedia.org/wikipedia/commons/e/ea/Uranus_(Edited).jpg");
addObject("BLUE", 1000, "m", "https://vignette2.wikia.nocookie.net/heman/images/3/36/Earth.jpg");
}
void draw() {
fill(0,0,0);
rect(0, 0, 1500, 800);
int x = 0 + xoffset;
for ( Object drawObject : ObjectList ) {
float dia = drawObject.diameter;
if (x+drawObject.img.width >= 0 && x <= 1500) {
//checks if image is too small to be drawn
int drawWidth = int(scale * dia);
int drawHeight = int(drawWidth * drawObject.hei / drawObject.wid);
if (drawWidth > 0 && drawHeight > 0) {
drawObject.img.resize(drawWidth, drawHeight);
image(drawObject.img, x, 400-(drawObject.img.height/2));
//calculates font size relative to object's current size
int textSize;
//checks if the name or diameter is longer, then uses the longer one for calculation
fill(255,255,255);
if (drawObject.name.length() < str(drawObject.diameter).length()) {
textSize = int(drawObject.img.width/str(drawObject.diameter).length());
} else {
textSize = int(drawObject.img.width/drawObject.name.length());
}
if (textSize > 0) {
textSize(textSize);
float texty = 418+(drawObject.img.height/2);
if (texty < (418+(drawObject.img.height/2))) {
texty = 418;
}
text(drawObject.name, x+(drawObject.img.width/2), texty);
text(drawObject.diameter+drawObject.unit, x+(drawObject.img.width/2), texty+textSize);
}
}
drawObject.xpos = x;
x += (drawObject.img.width*0.08 + drawObject.img.width);
}
//display deltax
textSize(32);
text(str(deltax), 1450, 10);
text(str(deltascale), 1450, 50);
println(str(scale));
}
}
void mouseWheel(MouseEvent event) {
float e = event.getCount();
if (e < 0) {
scale *= (1 + deltascale);
} else if (e > 0) {
scale *= (1 - deltascale) ;
}
}
void keyPressed() {
if (key == CODED) {
if (keyCode == LEFT) {
xoffset += deltax;
} else if (keyCode == RIGHT) {
xoffset -= deltax;
} else if (keyCode == UP) {
deltax += 5;
} else if (keyCode == DOWN) {
deltax -= 5;
}
}
if (key == 'r') {
//reloadObjects();
} else if (key == 'q') {
deltascale += 0.02;
} else if (key == 'a') {
deltascale -= 0.02;
}
if (deltax < 0) {
deltax = 0;
} else if (deltascale < 0) {
deltascale = 0;
}
}
以下原始代码将无法运行,因为它使用了只有我拥有的图像。
我希望有人能帮助我解决这个错误,或者帮助我改进我的算法。 编辑:代码现在可以验证并显示我遇到的问题
好吧,我注意到只要您的其中一张图片即将离开屏幕的左边缘,图像就会跳动。看起来您可能会在每个图像离开屏幕时以不同方式计算 x 位置。尝试摆脱你的 if (x+drawObject.img.width >= 0 && x <= 1500)
测试(暂时将其注释掉),但将代码保留在 if
.
几点:
- 绝对不要创建自己的对象class(正如 Kevin Workman 所说)
- 当您调用
img.resize()
时,您正在对图像数据重新采样,这会随着时间的推移导致质量下降。最好只对image()
函数使用width, height
参数(或使用scale()
转换函数——但这可能更令人困惑)。然后在其余的绘图代码中使用drawWidth/Height
而不是img.width/height
。 - 如果你想将图像居中,只需使用
imageMode(CENTER)
而不是自己计算 - 特别是因为看起来你正在使用 'magic number'400
- 尽量不要使用原始数字作为您的屏幕尺寸 - 而是使用
width
和height
全局变量 - 当您更改屏幕尺寸时,它会让您的生活更轻松。