Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Java
  4. Implementing a "Paint Can"-type tool

Implementing a "Paint Can"-type tool

Scheduled Pinned Locked Moved Java
helpdata-structuresc++csstools
6 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    max29297
    wrote on last edited by
    #1

    Hey guys! So I've been trying to get this utility method to work for a while and can't seem to stop overloading the stack. The method should be able to emulate the Paint Can Tool in MS Paint. It takes a BufferedImage, the x- and y-coordinates of the point to apply the method to, and the color with which to paint the area. My implementation is a recursive one, and I know this is the reason for the overflow, but I haven't done any complex recursive method writing as of yet and don't know how I can fix my problem. Here is the code I've written:

    static void paintCan(BufferedImage image, int x, int y, Color color) {
    int[][] array = new int[image.getWidth()][image.getHeight()];

    for (int r = 0; r < image.getHeight(); r++)
    	for (int c = 0; c < image.getWidth(); c++)
    		array\[c\]\[r\] = image.getRGB(c, r);
    		
    changeColor(array, x, y, array\[x\]\[y\], color.getRGB());
    
    for (int r = 0; r < image.getHeight(); r++)
    	for (int c = 0; c < image.getWidth(); c++)
    		image.setRGB(c, r, array\[c\]\[r\]);
    

    }

    static void changeColor(int[][] image, int x, int y, int from, int to) {
    if (image[x][y] == from) {
    image[x][y] = to;

    	int left = x - 1;
    	int right = x + 1;
    	int up = y - 1;
    	int down= y + 1;
    	
    	if (left >= 0)
    		changeColor(image, left, y, from, to);
    	if (right < image.length)
    		changeColor(image, right, y, from, to);
    	if (up >= 0)
    		changeColor(image, x, up, from, to);
    	if (down < image\[0\].length)
    		changeColor(image, x, down, from, to);
    }
    

    }

    This method works perfectly for smaller areas, but when the area selected at the (x, y) point requires too much recursion, a runtime error is thrown. Does anyone know how I can get the method to use less memory and not overload the stack? Help is very appreciated :) Thank you! -max

    4 1 Reply Last reply
    0
    • M max29297

      Hey guys! So I've been trying to get this utility method to work for a while and can't seem to stop overloading the stack. The method should be able to emulate the Paint Can Tool in MS Paint. It takes a BufferedImage, the x- and y-coordinates of the point to apply the method to, and the color with which to paint the area. My implementation is a recursive one, and I know this is the reason for the overflow, but I haven't done any complex recursive method writing as of yet and don't know how I can fix my problem. Here is the code I've written:

      static void paintCan(BufferedImage image, int x, int y, Color color) {
      int[][] array = new int[image.getWidth()][image.getHeight()];

      for (int r = 0; r < image.getHeight(); r++)
      	for (int c = 0; c < image.getWidth(); c++)
      		array\[c\]\[r\] = image.getRGB(c, r);
      		
      changeColor(array, x, y, array\[x\]\[y\], color.getRGB());
      
      for (int r = 0; r < image.getHeight(); r++)
      	for (int c = 0; c < image.getWidth(); c++)
      		image.setRGB(c, r, array\[c\]\[r\]);
      

      }

      static void changeColor(int[][] image, int x, int y, int from, int to) {
      if (image[x][y] == from) {
      image[x][y] = to;

      	int left = x - 1;
      	int right = x + 1;
      	int up = y - 1;
      	int down= y + 1;
      	
      	if (left >= 0)
      		changeColor(image, left, y, from, to);
      	if (right < image.length)
      		changeColor(image, right, y, from, to);
      	if (up >= 0)
      		changeColor(image, x, up, from, to);
      	if (down < image\[0\].length)
      		changeColor(image, x, down, from, to);
      }
      

      }

      This method works perfectly for smaller areas, but when the area selected at the (x, y) point requires too much recursion, a runtime error is thrown. Does anyone know how I can get the method to use less memory and not overload the stack? Help is very appreciated :) Thank you! -max

      4 Offline
      4 Offline
      4277480
      wrote on last edited by
      #2

      I did some testing with your code and here are my results: 1. Image size does not effect result. 2. The Pixels in your image cause the stack overflow. - When your image is mono colored. - When your image contain n colors in shapes lets say black square, green circle etc... The above throw the Exception - When approximately all pixels of the image vary then your code works fine with any size even with 1920 x 1080. If you want to use the bucket feature in MS Paint here is a simpler way:

      BufferedImage image = ImageIO.read(new File("Desert.jpg")); // image from sample images in Win 7 RC
      Color c = Color.red;
      int x0 = 10,x1 = 100,y0 = 10,y1 = 100;
      for (int i = x0; i < x1; i++)
      {
      for (int j = y0; j < y1; j++)
      {
      image.setRGB(i, j, c.getRGB());
      }
      }
      ImageIO.write(image, "jpg", new File("Result.jpg"));

      By the way the recursion problem is in the change color method. Hope this help

      M 1 Reply Last reply
      0
      • 4 4277480

        I did some testing with your code and here are my results: 1. Image size does not effect result. 2. The Pixels in your image cause the stack overflow. - When your image is mono colored. - When your image contain n colors in shapes lets say black square, green circle etc... The above throw the Exception - When approximately all pixels of the image vary then your code works fine with any size even with 1920 x 1080. If you want to use the bucket feature in MS Paint here is a simpler way:

        BufferedImage image = ImageIO.read(new File("Desert.jpg")); // image from sample images in Win 7 RC
        Color c = Color.red;
        int x0 = 10,x1 = 100,y0 = 10,y1 = 100;
        for (int i = x0; i < x1; i++)
        {
        for (int j = y0; j < y1; j++)
        {
        image.setRGB(i, j, c.getRGB());
        }
        }
        ImageIO.write(image, "jpg", new File("Result.jpg"));

        By the way the recursion problem is in the change color method. Hope this help

        M Offline
        M Offline
        max29297
        wrote on last edited by
        #3

        I was aware that it was not the image size, but the number of pixels in the shape being filled that was the problem, and that the recursion overflow error was occurring in the changeColor() method... Your solution does not implement the bucket feature in MS Paint, because when you use the paint bucket in Paint it fills all adjacent pixels of a similar color with the color of your choice, what you have given me only fills a rectangle with a certain color :/ Thanks for the reply though!

        M 1 Reply Last reply
        0
        • M max29297

          I was aware that it was not the image size, but the number of pixels in the shape being filled that was the problem, and that the recursion overflow error was occurring in the changeColor() method... Your solution does not implement the bucket feature in MS Paint, because when you use the paint bucket in Paint it fills all adjacent pixels of a similar color with the color of your choice, what you have given me only fills a rectangle with a certain color :/ Thanks for the reply though!

          M Offline
          M Offline
          max29297
          wrote on last edited by
          #4

          I think I found the answer guys. My main problem for looking for help with my problem was that I didn't know what the "paint can tool" functionality was called! But it turns out there is something called the Flood Fill Algorithm that is exactly what I'm talking about implementing. http://en.wikipedia.org/wiki/Flood_fill[^]

          4 1 Reply Last reply
          0
          • M max29297

            I think I found the answer guys. My main problem for looking for help with my problem was that I didn't know what the "paint can tool" functionality was called! But it turns out there is something called the Flood Fill Algorithm that is exactly what I'm talking about implementing. http://en.wikipedia.org/wiki/Flood_fill[^]

            4 Offline
            4 Offline
            4277480
            wrote on last edited by
            #5

            My bad, in my way I was trying to say that if you give the coordinates of the pixels then use the graphics class to fill in the color but its not practical any way here is a nice implementation of the specified algorithm: http://www.cis.upenn.edu/~matuszek/cit594-2005/ Check FloodFillApplet.java and ColorArrayComponent.java Good luck

            S 1 Reply Last reply
            0
            • 4 4277480

              My bad, in my way I was trying to say that if you give the coordinates of the pixels then use the graphics class to fill in the color but its not practical any way here is a nice implementation of the specified algorithm: http://www.cis.upenn.edu/~matuszek/cit594-2005/ Check FloodFillApplet.java and ColorArrayComponent.java Good luck

              S Offline
              S Offline
              sharkbc
              wrote on last edited by
              #6

              Hi ! I think you should use the floodfill algorithms using stack or quee (without a recursive menthod). Because wehn use any recursive menthod it eat alot of memorry and the _stack is limit or very small for your code to execute. This is the link. http://hughm.cs.ukzn.ac.za/~murrellh/ds/code/floodfill/Stacks_and_Queues.html[^] Hope this helpul ! Regards !

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups