如何更快地渲染数组? [英] How can I more quickly render my array?

查看:69
本文介绍了如何更快地渲染数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究Java中的



但是,我遇到两个问题:


  1. 此功能非常慢。对执行进行性能分析后,我看到90%的执行时间都花在了该功能上。按照注释中的建议将函数分解为两位之后,我得到以下配置文件: < img src = https://i.stack.imgur.com/Nmx5l.png alt = profile>

  2. 不是写入.png文件,我希望使用 JFrame 显示图像,但是(同样,由于我错过了对Java的正确介绍), JFrame 似乎不是我最好的朋友,我似乎也无法弄清楚如何使用它们。

是否可以一次填充整个100x100像素的单元格?有没有一种方法不必每次都创建整个 BufferedImage ,而只需修改在另一种方法中已更改的位?我是否应该使用 BufferedImage 以外的其他东西?

解决方案

好吧,所以我的代码需要什么元素,有人可以编写出示例方法还是所需的代码片段?看起来写文件实际上不是您的最大问题,看起来您的最大问题是您逐个转储像素。我可能会做一些事情:


  1. 制作较小的图像。 100x100很多。为什么不20x20?您始终可以使用图像编辑器进行放大。

  2. 完全跳过 int [] 步,然后写入 BufferedImage 直接。


    • 使用 bufferedImage.setRGB(startX,startY,w,h,rgbArray,offset,scansize)就像您一直在做的一样,但只针对您要批量绘制的图像部分。


  3. 根据 a b 的值(与 w h ,包括尤其是循环,请参见第4点。

  4. 完全牢固地填充框,然后通过覆盖添加内部矩形这些复杂的if检查会破坏您的性能。执行无分支(如果没有if语句),它将运行得更快。

  5. 将for循环内的代码放入使其变得更清晰的另一种方法,如 drawSingleBox 之类。

请记住,更多具有好名的方法可以更轻松地跟踪正在发生的事情。 writeImageToFile toImage3 更为可取。 code> convertArra yToImage 比 toImage2 更为可取。



此外,您还问过如何放置图片作为 JFrame 的背景;一旦完全绘制了 BufferedImage 对象,就可以使用 JFrame背景中的信息图片来完成其中的一部分。


I have been working on a nonogram solver in Java, and all of my algorithm works fine, but I have been struggling with the visualization a little bit.

During the execution of the algorithm, I have access to two "solution-arrays". One is of type int[][], and contains values -1 for "certainly white", 0 for "uncertain" and 1 for "certainly black". Another array is of type float[][] which contains values between 0 and 1, here 0 is for certainly white, 1 is for certainly black and a value of .2 indicates it is more likely for the cell to be white than it to be black.

Since I've recently switched from PHP to Java programming (without proper introduction), I don't know much about visualizing this array properly. Of course I have first tried to simply print the first type of array to the console with characters like X, . and ?, but this is far from nice. I then found something about BufferedImage's, and I created the following function (for the float[][], the int[][] is similar):

public void toImage(int w, int h, float[][] solution) throws IOException {
    int[] data = toImage1(w, h, solution);
    BufferedImage img = toImage2(data, w, h);
    toImage3(img);
}

public int[] toImage1(int w, int h, float[][] solution) throws IOException {
    int[] data = new int[w * h];
    int i = 0;
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            int a = y / 100;
            int b = x / 100;
            int z = (int) (255 * Math.sqrt(1 - solution[a][b]));
            if (solution[a][b] == 1 && ((((y % 100 >= 10 && y % 100 <= 15) || (y % 100 >= 85 && y % 100 <= 90)) && x % 100 >= 10 && x % 100 <= 90) || (((x % 100 >= 10 && x % 100 <= 15) || (x % 100 >= 85 && x % 100 <= 90)) && y % 100 >= 10 && y % 100 <= 90))) {
                z = 100;
            } else if (solution[a][b] == 0 && ((((y % 100 >= 10 && y % 100 <= 15) || (y % 100 >= 85 && y % 100 <= 90)) && x % 100 >= 10 && x % 100 <= 90) || (((x % 100 >= 10 && x % 100 <= 15) || (x % 100 >= 85 && x % 100 <= 90)) && y % 100 >= 10 && y % 100 <= 90))) {
                z = 230;
            }
            data[i++] = z << 16 | z << 8 | z;
        }
    }
    return data;
}

public BufferedImage toImage2(int[] data, int w, int h) {
    BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
    img.setRGB(0, 0, w, h, data, 0, w);
    return img;
}

public void toImage3(BufferedImage img) throws IOException {
    File f = new File("Nonogram.png");
    ImageIO.write(img, "PNG", f);
}

Here, w and h are supposed to be the amount of cells in each column resp. row multiplied by 100 (I want each cell to be represented by a block of 100x100 pixels). I then also want an extra gray box in cells that are certain, that's what the if and else if are for.

This works beautifully, and creates images like this:

However, I run into two problems:

  1. This function is super slow. After profiling the execution, I see 90% of the execution time goes to this function. After breaking down my function into two bits, as suggested in the comments, I get the following profile:
  2. Instead of writing to a .png file, I would like a JFrame to display my image, but (again since I missed my proper introduction to Java), JFrame's don't seem to be my best friends and I can't seem to work out how to use them.

Is there a possibility to fill entire 100x100 px cells at once? Is there a way to not have to create the entire BufferedImage each time over, but just modify the bits that have changed in another method? Should I use something else than BufferedImage? What elements does my code need, could someone code out an example method, or the needed code snippets?

解决方案

Okay, so it looks like writing to a file is not actually your biggest problem, it looks like your biggest problem is that you're dumping the pixels individually. Here are some things I might do:

  1. Make a smaller image. 100x100 is a lot. Why not 20x20? You can always zoom in with an image editor.
  2. Skip the int[] step entirely, and write to the BufferedImage directly.
    • Use bufferedImage.setRGB(startX, startY, w, h, rgbArray, offset, scansize) as you've been doing, but only for the section of the image you're drawing in bulk.
  3. Do everything based on the values of a and b (as opposed to w and h, including and especially the loops, see point 4.
  4. Fill the the boxes completely solidly, then add the inner rectangle by overwriting those lines separately. All these complicated if checks are killing your performance. Do it branchless (no if statements), and it will run much faster.
  5. Put the code that's inside the for loops into a separate method that makes it more clear. Call it something like drawSingleBox.

Remember, more methods with good names make it easier to follow what's going on. writeImageToFile is preferred over toImage3. convertArrayToImage is preferred over toImage2.

Also, you asked about how to put an image as the background of a JFrame; once you have your fully drawn BufferedImage object, you can use the information in JFrame background image to do that part of it.

这篇关于如何更快地渲染数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆