如何在JAVA中更快地完成渲染过程?

时间:2017-11-22 08:22:38

标签: java graphics render

我正在制作一个具有屏幕过滤过程的软件。代码已经可以移动颜色并将其应用到框架,唯一的问题是过滤窗口渲染需要大约40-50秒。有什么方法可以让它更快吗?我还想问一下代码的哪一部分会使这个过程更长,更耗时。我真的很感激你的帮助。谢谢!

这是我的代码。

 public RedGreenFilter(int k1, int k2, int k3) {
        this.k1 = k1;
        this.k2 = k2;
        this.k3 = k3;
 }

    @Override
    public BufferedImage filter(final BufferedImage src, BufferedImage dst) {
        if (dst == null) {
            dst = this.createCompatibleDestImage(src, null);
        }

        // make sure the two images have the same size, color space, etc.
        // MISSING !!! ???

        DataBufferInt inBuffer = (DataBufferInt) src.getRaster().getDataBuffer();
        DataBufferInt outBuffer = (DataBufferInt) dst.getRaster().getDataBuffer();
        int[] inData = inBuffer.getData();
        int[] outData = outBuffer.getData();



        int simR = 0, simG = 0, simB = 0, mild = 10, moderate = 20, strong = 40;
        float cIndex = MyDeficiency.cIndex;
        float angle = MyDeficiency.angle;
        float x = 0, y = 0, z = 0;

        int prevIn = 0;
        int prevOut = 0;
        final int length = inData.length;

        int corrG;
        int corrR;
        int corrB;

        int SizeOfScreen = src.getHeight() * src.getWidth();



        final int[] redArray = new int[SizeOfScreen];
        final int[] blueArray = new int[SizeOfScreen];
        final int[] greenArray = new int[SizeOfScreen];



        for (int i = 0; i < SizeOfScreen; i++) {
            final int in = inData[i];
            if (in == prevIn) {
                outData[i] = prevOut;
            } else {

                final int r = (0xff0000 & in) >> 16;
                final int g = (0xff00 & in) >> 8;
                final int b = 0xff & in;

                // get linear rgb values in the range 0..2^15-1
                final int r_lin = rgb2lin_red_LUT[r];
                final int g_lin = rgb2lin_red_LUT[g];
                final int b_lin = rgb2lin_red_LUT[b];

               //http://publication.gunadarma.ac.id/bitstream/123456789/12232/1/Slide_Mahendra_54411250.pdf 
               float L = (17.8824f * r + 43.5161f * g + 4.11935f * b);
               float M = (3.4565f * r + 27.1554f * g + 3.86714f * b);
               float S = (0.02996f * r + 0.18431f * g + 1.46709f * b); 

               float dL = ( 0 * L + 2.02344f * M - 2.52581f * S);
               float dM = ( 0 * L + 1 * M + 0 * S);
               float dS = ( 0 * L + 0 * M + 1 * S);

               float pL = ( 1 * L + 0 * M + 0 * S);
               float pM = ( 0.494207f * L + 0 * M + 1.24827f * S);
               float pS = ( 0 * L + 0 * M + 1 * S);    

                // simulated red and green are identical
                // scale the matrix values to 0..2^15 for integer computations 
                // of the simulated protan values.
                // divide after the computation by 2^15 to rescale.
                // also divide by 2^15 asnd multiply by 2^8 to scale the linear rgb to 0..255
                // total division is by 2^15 * 2^15 / 2^8 = 2^22
                // shift the bits by 22 places instead of dividing
                int r_blind = (int) (k1 * r_lin + k2 * g_lin) >> 22;
                int b_blind = (int) (k3 * r_lin - k3 * g_lin + 32768 * b_lin) >> 22;

                if (r_blind < 0) {
                    r_blind = 0;
                } else if (r_blind > 255) {
                    r_blind = 255;
                }

                if (b_blind < 0) {
                    b_blind = 0;
                } else if (b_blind > 255) {
                    b_blind = 255;
                }

                // convert reduced linear rgb to gamma corrected rgb
                int red = lin2rgb_LUT[r_blind];
                red = red >= 0 ? red : 256 + red; // from unsigned to signed
                int blue = lin2rgb_LUT[b_blind];
                blue = blue >= 0 ? blue : 256 + blue;   // from unsigned to signed

               if(k1 == 9591 && k2 == 23173){
                   x = dL;
                   y = dM;
                   z = dS;
               }

               if(k1 == 3683 && k2 == 29084){
                   x = pL;
                   y = pM;
                   z = pS;
               }

               //SEVERITY

               //PROTAN
               //normal to mild
               if (angle > 0.70 && cIndex < 1.2){
                    simR = (int)(0.0809533970341018f * x -0.1305188419612954f * y + 0.11673398252989027f * z);
                    simG = (int)(-0.01025222049871863f * x + 0.054025275314902886f * y -0.11362003603724172f * z);
                    simB = (int)(-0.0003651971010795924f * x -0.004121801653701777f * y + 0.693511617368688f * z);
                }
               //mild to moderate
               else if (angle > 0.70 && cIndex < 3 && cIndex > 1.20){
                    simR = (int)(0.0809533970341018f * x -0.1305188419612954f * y + 0.11673398252989027f * z) + mild;
                    simG = (int)(-0.01025222049871863f * x + 0.054025275314902886f * y -0.11362003603724172f * z);
                    simB = (int)(-0.0003651971010795924f * x -0.004121801653701777f * y + 0.693511617368688f * z);
                }

               //moderate to strong
               else if (angle > 0.70 && cIndex < 4 && cIndex > 3){
                    simR = (int)(0.0809533970341018f * x -0.1305188419612954f * y + 0.11673398252989027f * z) + moderate;
                    simG = (int)(-0.01025222049871863f * x + 0.054025275314902886f * y -0.11362003603724172f * z);
                    simB = (int)(-0.0003651971010795924f * x -0.004121801653701777f * y + 0.693511617368688f * z); 
                }

               //strong to super strong
               else if (angle > 0.70 && cIndex > 4){
                    simR = (int)(0.0809533970341018f * x -0.1305188419612954f * y + 0.11673398252989027f * z) + strong;
                    simG = (int)(-0.01025222049871863f * x + 0.054025275314902886f * y -0.11362003603724172f * z);
                    simB = (int)(-0.0003651971010795924f * x -0.004121801653701777f * y + 0.693511617368688f * z); 
                }

               //DEUTAN
               //normal to mild
               if (angle < 0.70 && angle > -65.00 && cIndex < 1.2){
                    simR = (int)(0.0809533970341018f * x -0.1305188419612954f * y + 0.11673398252989027f * z);
                    simG = (int)(-0.01025222049871863f * x + 0.054025275314902886f * y -0.11362003603724172f * z);
                    simB = (int)(-0.0003651971010795924f * x -0.004121801653701777f * y + 0.693511617368688f * z);
                }
               //mild to moderate
               else if (angle < 0.70 && angle > -65.00 && cIndex < 3 && cIndex > 1.20){
                    simR = (int)(0.0809533970341018f * x -0.1305188419612954f * y + 0.11673398252989027f * z);
                    simG = (int)(-0.01025222049871863f * x + 0.054025275314902886f * y -0.11362003603724172f * z) + mild;
                    simB = (int)(-0.0003651971010795924f * x -0.004121801653701777f * y + 0.693511617368688f * z);
                }

               //moderate to strong
               else if (angle < 0.70 && angle > -65 && cIndex < 4 && cIndex > 3){
                    simR = (int)(0.0809533970341018f * x -0.1305188419612954f * y + 0.11673398252989027f * z);
                    simG = (int)(-0.01025222049871863f * x + 0.054025275314902886f * y -0.11362003603724172f * z) + moderate;
                    simB = (int)(-0.0003651971010795924f * x -0.004121801653701777f * y + 0.693511617368688f * z) ; 
                }

               //strong to super strong
               else if (angle < 0.7 && angle > -65 && cIndex > 4){
                    simR = (int)(0.0809533970341018f * x -0.1305188419612954f * y + 0.11673398252989027f * z);
                    simG = (int)(-0.01025222049871863f * x + 0.054025275314902886f * y -0.11362003603724172f * z) + strong;
                    simB = (int)(-0.0003651971010795924f * x -0.004121801653701777f * y + 0.693511617368688f * z) ; 
                }

                int errR = r - simR;
                int errG = g - simG;      
                int errB = b - simB;

                float errModR = (0 * errR + 0 * errG + 0 * errB);
                float errModG = (0.7f * errR + 1 * errG + 0 * errB);
                float errModB = (0.7f * errR + 0 * errG + 1 * errB);


                corrR = (int) errModR + r;
                corrG = (int) errModG + g;
                corrB = (int) errModB + b;

                /*
                int corrR = 0;
                int corrG = 0;
                int corrB = 0;
                */
                //MyDeficiency my = new MyDeficiency();

                if(r == 255 && g == 255 && b == 255){
                    corrR = corrG = corrB = 255;
                }
                if(r == 0 && g == 0 && b == 0){
                    corrR = corrG = corrB = 0;
                }


                final int out = 0xff000000 | (corrR << 16) | (corrG << 8) | corrB ;

                redArray[i] = (out >> 16) & 0xFF;
                greenArray[i] = (out >> 8) & 0xFF;
                blueArray[i] = (out >> 0) & 0xFF; 

                //System.out.println("r: " +" " + redArray[i]+  " "+ " g:" +" " +greenArray[i] +" " +"b:"+" "+ blueArray[i] + " " +"i:"+ " "+i);

                //System.out.println("sR: " + (red << 16) + "sG: " +(red <<8)+ " sB: " + blue);




               //outData[i] = out;
                //prevIn = in;
               //prevOut = out;


            }
        }
            //System.out.println(SizeOfScreen);


        Window w = new Window(null);
        w.add(new JComponent() {
            public void paintComponent(Graphics g) {
                int alpha = 190; // 50% transparent
                int pixelcounter = 0;
                for(int i = 0; i < src.getHeight(); i++){
                   for(int j = 0; j < src.getWidth(); j++){
                        Color myColour = new Color(redArray[pixelcounter],greenArray[pixelcounter],blueArray[pixelcounter], alpha);
                        g.setColor(myColour);
                        g.fillRect(j,i,1,1);
                        pixelcounter++;
                    }

                }

            }

            public Dimension getPreferredSize() {
                return new Dimension(src.getWidth(), src.getHeight());
            }
            });
            w.pack();
            w.setLocationRelativeTo(null);

            w.setAlwaysOnTop(true);

/**
* This sets the background of the window to be transparent.
*/
            AWTUtilities.setWindowOpaque(w, false);
            setTransparent(w);

            w.setVisible(true); 

            //w.setVisible(false);


        return dst;
    }
}

0 个答案:

没有答案