Java blur Image

后端 未结 7 1715
臣服心动
臣服心动 2021-01-11 17:48

I am trying to blur the image

   int radius = 11;
    int size = radius * 2 + 1;
    float weight = 1.0f / (size * size);
    float[] data = new float[size *         


        
相关标签:
7条回答
  • 2021-01-11 18:15

    You can use opencv library to make complete image blur.

    0 讨论(0)
  • 2021-01-11 18:17

    I always do something like this:

    public BufferedImage diagonalBlur(int range, int angle)
        {
            BufferedImage b = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = b.createGraphics();
            
            for(int x = 0; x < main_image.getWidth(); x++)
            {
                for(int y = 0; y < main_image.getHeight(); y++)
                    
                    int red[] = new int[range * 2], green[] = new int[range * 2], blue[] = new int[range * 2];
                    int pixels[] = new int[range * 2];
                    
                    for(int i = 0; i < pixels.length; i++)
                    {
                        pixels[i] = main_image.getRGB(clamp(x - clamp(range / 2, 0, range) + i, 0, main_image.getWidth() - 1), clamp(y - clamp(range / 2, 0, range) + (int)(i * Math.toRadians(angle)), 0, main_image.getHeight() - 1));
                        
                        red[i] = (pixels[i] >> 16) & 0xff;
                        green[i] = (pixels[i] >> 8) & 0xff;
                        blue[i] = (pixels[i]) & 0xff;
                    }
                    
                    int red_t = 0, green_t = 0, blue_t = 0;
                    
                    for(int i = 0; i < pixels.length; i++)
                    {
                        red_t += red[i];
                        green_t += green[i];
                        blue_t += blue[i];
                    }
                    
                    int r = red_t / (range * 2);
                    int gr = green_t / (range * 2);
                    int bl = blue_t / (range * 2);
                    
                    //System.out.println(r + ", " + gr + ", " + bl);
                    
                    g.setColor(new Color(r, gr, bl));
                    g.fillRect(x, y, 1, 1);
                    
                }
            }
            g.dispose();
            
            return b;
    

    then, doing something along the lines of:

    public static void main(String a[])
    {
      File f = new File("path");
      try{
        ImageIO.write(diagonalBlur(10, 69), "png", f);
      }
      catch(IOException e)
      {
        e.printStackTrace();
      }
    }
    }
    

    That should save the file as a BufferedImage. of course, you need a reference to an image. In the code I used main_image, but that was a variable I created earlier:

    public BufferedImage main_image;
    

    to initiate it I used

    try
    {
      main_image = ImageIO.read(new File("path"));
    }
    catch(IOException e)
    {
      e.printStackTrace();
    }
    

    in the main method. Adding a little bit of JFrame code, allowed me to do this: blur If you want to have a gaussian blur, you just have to make the red, green, blue and pixels variable a 2-dimensional array and repeat the proccess for the y-axis. I hope I could help.

    0 讨论(0)
  • 2021-01-11 18:28

    That is because you are using ConvolveOp.EDGE_NO_OP in this line:

    ConvolveOp op = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
    

    The API documentation says:

    Pixels at the edge of the source image are copied to the corresponding pixels in the destination without modification.

    Try EDGE_ZERO_FILL - that will give you black borders.

    You can also try to cut off the edges after blurring.

    The reason for why it can't do the edges has to do with how the algorithm works.

    0 讨论(0)
  • 2021-01-11 18:31

    You can't blur one pixel. This sounds obvious, but when you think about it, what is the minimum? To blur a pixel, you need neighboring pixels.

    The problem here is that at the edges and corners, the pixels have too few neighbours – the blur algorith has too few pixels to use. It has no pixels "outside" the image with which to blur, so it will just leave those as-is.

    The solution is either to extend the picture somehow (do you have a larger source image available?), or to cut off the non-blurred bits when you are done. Both are essentially the same.

    0 讨论(0)
  • 2021-01-11 18:34

    I found this once when I was looking for a blur ability for documents when the ConvolveOp class didn't cut it (for the reasons you are running into). It does a Gaussian blur which is the most natural blur imho... Hopefully it will help you. I retrieved it from this webpage: Java Image Processing...

    /*
    ** Copyright 2005 Huxtable.com. All rights reserved.
    */
    
    package com.jhlabs.image;
    
    import java.awt.image.*;
    
    /**
     * A filter which applies Gaussian blur to an image. This is a subclass of ConvolveFilter
     * which simply creates a kernel with a Gaussian distribution for blurring.
     * @author Jerry Huxtable
     */
    public class GaussianFilter extends ConvolveFilter {
    
        static final long serialVersionUID = 5377089073023183684L;
    
        protected float radius;
        protected Kernel kernel;
    
        /**
         * Construct a Gaussian filter
         */
        public GaussianFilter() {
            this(2);
        }
    
        /**
         * Construct a Gaussian filter
         * @param radius blur radius in pixels
         */
        public GaussianFilter(float radius) {
            setRadius(radius);
        }
    
        /**
         * Set the radius of the kernel, and hence the amount of blur. The bigger the radius, the longer this filter will take.
         * @param radius the radius of the blur in pixels.
         */
        public void setRadius(float radius) {
            this.radius = radius;
            kernel = makeKernel(radius);
        }
    
        /**
         * Get the radius of the kernel.
         * @return the radius
         */
        public float getRadius() {
            return radius;
        }
    
        public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
            int width = src.getWidth();
            int height = src.getHeight();
    
            if ( dst == null )
                dst = createCompatibleDestImage( src, null );
    
            int[] inPixels = new int[width*height];
            int[] outPixels = new int[width*height];
            src.getRGB( 0, 0, width, height, inPixels, 0, width );
    
            convolveAndTranspose(kernel, inPixels, outPixels, width, height, alpha, CLAMP_EDGES);
            convolveAndTranspose(kernel, outPixels, inPixels, height, width, alpha, CLAMP_EDGES);
    
            dst.setRGB( 0, 0, width, height, inPixels, 0, width );
            return dst;
        }
    
        public static void convolveAndTranspose(Kernel kernel, int[] inPixels, int[] outPixels, int width, int height, boolean alpha, int edgeAction) {
            float[] matrix = kernel.getKernelData( null );
            int cols = kernel.getWidth();
            int cols2 = cols/2;
    
            for (int y = 0; y < height; y++) {
                int index = y;
                int ioffset = y*width;
                for (int x = 0; x < width; x++) {
                    float r = 0, g = 0, b = 0, a = 0;
                    int moffset = cols2;
                    for (int col = -cols2; col <= cols2; col++) {
                        float f = matrix[moffset+col];
    
                        if (f != 0) {
                            int ix = x+col;
                            if ( ix < 0 ) {
                                if ( edgeAction == CLAMP_EDGES )
                                    ix = 0;
                                else if ( edgeAction == WRAP_EDGES )
                                    ix = (x+width) % width;
                            } else if ( ix >= width) {
                                if ( edgeAction == CLAMP_EDGES )
                                    ix = width-1;
                                else if ( edgeAction == WRAP_EDGES )
                                    ix = (x+width) % width;
                            }
                            int rgb = inPixels[ioffset+ix];
                            a += f * ((rgb >> 24) & 0xff);
                            r += f * ((rgb >> 16) & 0xff);
                            g += f * ((rgb >> 8) & 0xff);
                            b += f * (rgb & 0xff);
                        }
                    }
                    int ia = alpha ? PixelUtils.clamp((int)(a+0.5)) : 0xff;
                    int ir = PixelUtils.clamp((int)(r+0.5));
                    int ig = PixelUtils.clamp((int)(g+0.5));
                    int ib = PixelUtils.clamp((int)(b+0.5));
                    outPixels[index] = (ia << 24) | (ir << 16) | (ig << 8) | ib;
                    index += height;
                }
            }
        }
    
        /**
         * Make a Gaussian blur kernel.
         */
        public static Kernel makeKernel(float radius) {
            int r = (int)Math.ceil(radius);
            int rows = r*2+1;
            float[] matrix = new float[rows];
            float sigma = radius/3;
            float sigma22 = 2*sigma*sigma;
            float sigmaPi2 = 2*ImageMath.PI*sigma;
            float sqrtSigmaPi2 = (float)Math.sqrt(sigmaPi2);
            float radius2 = radius*radius;
            float total = 0;
            int index = 0;
            for (int row = -r; row <= r; row++) {
                float distance = row*row;
                if (distance > radius2)
                    matrix[index] = 0;
                else
                    matrix[index] = (float)Math.exp(-(distance)/sigma22) / sqrtSigmaPi2;
                total += matrix[index];
                index++;
            }
            for (int i = 0; i < rows; i++)
                matrix[i] /= total;
    
            return new Kernel(rows, 1, matrix);
        }
    
        public String toString() {
            return "Blur/Gaussian Blur...";
        }
    }
    
    0 讨论(0)
  • 2021-01-11 18:40

    If you frequently deal with pictures in your application, you may want to consider using the ImageJ API: It packs functionality on quite a lot of image processing tasks, including blurring.

    Their Gaussian Blur filter will blur right to the edge of the picture, by making the following assumption

    {...} it assumes that out-of-image pixels have a value equal to the nearest edge pixel {...}

    Even if you don't want to change your code to use the ImageJ API, you may still find the above assumption useful to solving your problem.

    For more info, check out the GaussianBlur filter in the API documentation: http://rsb.info.nih.gov/ij/developer/api/ij/plugin/filter/GaussianBlur.html

    0 讨论(0)
提交回复
热议问题