上下文:我试图用Java创建一个动画。动画是简单地采取一个图像,并使它出现从最暗的像素到最亮。
问题:定义像素转换的内部算法不是我的问题。我对Java和一般计算都是新手。我做了一些研究,知道有很多API有助于图像筛选/转换。我的问题是表现,理解它。
对于实现,我创建了一个方法,它执行以下操作:
之后,我使用计时器调用该方法。返回的BufferedImage在每次调用后通过setIcon附加到JButton。
对于一个500x500的图像,我的机器需要大约3ms来处理每个呼叫。对于标准的1080p图像,它需要大约30毫秒,wich大约是每秒33帧。
我的目标是处理/动画的全高清图像在30fps...我不能用我正在走的路。在大多数电脑里都没有。
我搞错了什么?我怎么能让它更快?使用getDataBuffer或getPixels代替getSample可以改进吗?
提前感谢!抱歉我的英语。
部分结论:多亏了这里的一些帮助。我改变了观念。我没有使用getSample和setSample,而是将BufferedImage的像素ARGB信息存储到一个数组中。因此,我处理了数组,并将其一次复制到另一个BufferedImage的光栅中。
处理时间从30ms(获取/设置样本)缩短到1ms。(测量很差,但在相同的机器、环境和代码中)。
下面是我为实现它而编写的一个小类。该类只能过滤低于亮度级别的像素,其他像素变得透明(alpha=0)。
希望对未来寻找同样解决方案的人有所帮助。小心我在Java方面还不到新手水平,所以代码可能组织/优化得很差。
import java.awt.Graphics2D;
import java.awt.image.*;
/**
* @author Psyny
*/
public class ImageAppearFX {
//Essencial Data
BufferedImage imgProcessed;
int[] RAWoriginal;
int[] RAWprocessed;
WritableRaster rbgRasterProcessedW;
//Information about the image
int x,y;
int[] mapBrightness;
public ImageAppearFX(BufferedImage inputIMG) {
//Store Dimensions
x = inputIMG.getWidth();
y = inputIMG.getHeight();
//Convert the input image to INT_ARGB and store it.
this.imgProcessed = new BufferedImage(x, y, BufferedImage.TYPE_INT_ARGB);
Graphics2D canvas = this.imgProcessed.createGraphics();
canvas.drawImage(inputIMG, 0, 0, x, y, null);
canvas.dispose();
//Create an int Array of the pixels informations.
//p.s.: Notice that the image was converted to INT_ARGB
this.RAWoriginal = ((DataBufferInt) this.imgProcessed.getRaster().getDataBuffer()).getData();
//Dupplication of original pixel array. So we can make changes based on original image
this.RAWprocessed = this.RAWoriginal.clone();
//Get Raster. We will need the raster to write pixels on
rbgRasterProcessedW = imgProcessed.getRaster();
//Effect Information: Store brightness information
mapBrightness = new int[x*y];
int r,g,b,a,greaterColor;
// PRocess all pixels
for(int i=0 ; i < this.RAWoriginal.length ; i++) {
a = (this.RAWoriginal[i] >> 24) & 0xFF;
r = (this.RAWoriginal[i] >> 16) & 0xFF;
g = (this.RAWoriginal[i] >> 8) & 0xFF;
b = (this.RAWoriginal[i] ) & 0xFF;
//Search for Stronger Color
greaterColor = r;
if( b > r ) {
if( g > b ) greaterColor = g;
else greaterColor = b;
} else if ( g > r ) {
greaterColor = g;
}
this.mapBrightness[i] = greaterColor;
}
}
//Effect: Show only in a certain percent of brightness
public BufferedImage BrightnessLimit(float percent) {
// Adjust input values
percent = percent / 100;
// Pixel Variables
int hardCap = (int)(255 * percent);
int r,g,b,a,bright;
// Process all pixels
for(int i=0 ; i < this.RAWoriginal.length ; i++) {
//Get information of a pixel of the ORIGINAL image
a = (this.RAWoriginal[i] >> 24) & 0xFF;
r = (this.RAWoriginal[i] >> 16) & 0xFF;
g = (this.RAWoriginal[i] >> 8) & 0xFF;
b = (this.RAWoriginal[i] ) & 0xFF;
//Brightness information of that same pixel
bright = this.mapBrightness[i];
//
if( bright > hardCap ) {
a = 0;
}
this.RAWprocessed[i] = ((a << 24) + (r << 16) + (g << 8) + ( b )); //Write ARGB in byte format
}
//Copy the processed array into the raster of processed image
rbgRasterProcessedW.setDataElements(0, 0, x, y, RAWprocessed);
return imgProcessed;
}
//Return reference to the processed image
public BufferedImage getImage() {
return imgProcessed;
}
}
虽然变化产生的时差并不能证明重复搜索是瓶颈,但它确实强烈地暗示了它。
如果您愿意/能够用内存换时间,我会首先按亮度对所有像素位置的列表进行排序。接下来,我会在动画中使用排序列表来查找下一个要复制的像素。
另外一个建议:使用Java内置的排序方法之一。做自己的东西是有教育意义的,但学习如何分类似乎不是你的目标。此外,如果我对瓶颈的猜测是错误的,你会希望尽量减少你的时间追求这个答案。
问题内容: 几个用户询问在numpy的或SciPy的[图像卷积的速度或存储器消耗1,2,3,4 ]。从回答和我使用Numpy的经验来看,与Matlab或IDL相比,我认为这可能是numpy的主要缺点。 到目前为止,没有一个答案能解决整个问题,所以这里是:“用Python计算2D卷积最快的方法是什么?” 常见的python模块是公平的游戏:numpy,scipy和PIL(其他?)。为了比较具有挑战性
问题内容: 我会写 我还可以使用其他哪些过滤器? 我可以使用这样的东西吗? 问题答案: Docker v1.13.0支持以下条件: 或用于按某些值过滤图像: 参考文献 码头工人图像过滤 码头工人文档
在Tableau中,使用度量和维度上的右键单击选项可以快速获得许多过滤器类型。这些过滤器具有足够的功能来解决大多数日常过滤需求。这些过滤器称为快速过滤器。 以下屏幕截图显示了如何访问快速过滤器: 下表给出了在Tableau中各种快速过滤器及其用法。 过滤器 作用/目的 单值(列表) 它在列表中一次只选择一个值。 单值(下拉) 它在下拉列表中选择单个值。 多值(列表) 它在列表中一次可选择一个或多个
视图过滤 可以对视图的渲染输出进行过滤 <?php namespace app\index\controller; use think\Controller; class Index extends Controller { public function index() { // 使用视图输出过滤 return $this->filter(fu
我需要在javafx tableview中实现一个拥有庞大数据(大约10万)的过滤器, 我试过这个教程。它可以工作,但与swing排序和过滤相比,过滤速度非常慢。 谁能帮我提速吗。 现在正在发生的事情是,当我键入textproperty change fire up和filterdata时,但速度很慢,我需要一些东西来显示筛选结果,并在swing中快速键入。 提前谢谢。 p、 我也看过这个。
问题内容: 我一直在尝试使用docker process命令获取docker实例的容器ID,但是当我尝试使用 名称 过滤器时,对我来说效果 很好 。 结果容器ID: 3c7e865f1dfb 但是,当我使用 图像进行 过滤时,我将获得所有实例容器ID: 结果容器ID: 5570dc09b581 3c7e865f1dfb 但我希望仅获得mariadb的容器ID。 如何使用过滤器作为图像获取Docke