Advertisement
Guest User

Aninimouse downscaling

a guest
Jun 29th, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.42 KB | None | 0 0
  1. #!/usr/bin/env python
  2. #
  3. # -------------------------------------------------------------------------------------
  4. #
  5. # Copyright (c) 2017, Dmitry Odintsov
  6. # This code is licensed under the MIT license (MIT)
  7. # (http://opensource.org/licenses/MIT)
  8. #
  9. # Permission is hereby granted, free of charge, to any person obtaining a copy of this
  10. # software and associated documentation files (the "Software"), to deal in the Software
  11. # without restriction, including without limitation the rights to use, copy, modify,
  12. # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
  13. # permit persons to whom the Software is furnished to do so, subject to the following
  14. # conditions:
  15. #
  16. # The above copyright notice and this permission notice shall be included in all copies
  17. # or substantial portions of the Software.
  18. #
  19. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  20. # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  21. # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  22. # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  23. # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  24. # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. #
  26. # -------------------------------------------------------------------------------------
  27. #
  28. # This is Python plug-in for GIMP.
  29. #
  30. # It can be executed by selecting the menu option: 'Filters/Aninimouse/Downscaling'
  31. # or by writing the following lines in the Python console (that can be opened with the
  32. # menu option 'Filters/Python-Fu/Console'):
  33. # >>> image = gimp.image_list()[0]
  34. # >>> gimp.pdb.python_fu_aniniscript(image, None, 8, 8)
  35.  
  36. from gimpfu import *
  37. import operator
  38.  
  39. def aniniscript(img, drawable, x_factor = 8, y_factor = 8) :
  40.     ''' Merges all visible layers and resizes the image by given factors.
  41.    Each pixel in the final image is colored with the dominant color in the according
  42.    [x_factor:y_factor] block of the old image.
  43.  
  44.    Parameters:
  45.    img         : the current image
  46.    drawable    : (unused)
  47.    x_factor    : X resize factor
  48.    y_factor    : Y resize factor
  49.    '''
  50.  
  51.     # If we have nothing to do or resulting width/height will be 0, abandon the task
  52.     if (x_factor == 1 and y_factor == 1) or (img.width / x_factor == 0 or img.height / y_factor == 0):
  53.         return
  54.  
  55.     # Indicates that the process has started.
  56.     gimp.progress_init("Aniniscaling the image...")
  57.  
  58.     # Set up an undo group, so the operation will be undone in one step.
  59.     pdb.gimp_image_undo_group_start(img)
  60.  
  61.     # Merge visible layers of the image
  62.     layer = img.merge_visible_layers(CLIP_TO_IMAGE)
  63.     bpp = layer.bpp
  64.     layerName = layer.name
  65.  
  66.     # Create a new layer to save the results (otherwise is not possible to undo the operation).
  67.     newLayer = gimp.Layer(img,
  68.         "Aniniscaled " + layerName,
  69.         layer.width / x_factor,
  70.         layer.height / y_factor,
  71.         layer.type,
  72.         layer.opacity,
  73.         layer.mode)
  74.  
  75.     img.add_layer(newLayer, 0)
  76.  
  77.     # Clear the new layer
  78.     pdb.gimp_edit_clear(newLayer)
  79.     newLayer.flush()
  80.  
  81.     try:
  82.         dstImage = newLayer.get_pixel_rgn(0, 0, newLayer.width, newLayer.height)
  83.  
  84.         # Calculate the number of tiles
  85.         tileX = int(layer.width / x_factor)
  86.         tileY = int(layer.height / y_factor)
  87.  
  88.         # Iterate over the tiles
  89.         for i in range(tileX):
  90.             for j in range(tileY):
  91.                 # Update the progress bar
  92.                 gimp.progress_update(float(i * tileY + j) / float(tileX * tileY))
  93.  
  94.                 # Get the tile
  95.                 srcTile = layer.get_pixel_rgn(i * x_factor, j * y_factor,
  96.                     x_factor, y_factor,
  97.                     False, False)
  98.  
  99.                 # Iterate over the pixels inside the tile
  100.                 blockColors = {}
  101.                 for x in range(x_factor):
  102.                     for y in range(y_factor):
  103.                         # Get pixel color and count it towards block color
  104.                         color = srcTile[i * x_factor + x, j * y_factor + y]
  105.                         if color not in blockColors:
  106.                             blockColors[color] = 0
  107.                         blockColors[color] += 1
  108.  
  109.                 # Get dominant color and paint in resulting image
  110.                 color = max(blockColors.iteritems(), key=operator.itemgetter(1))[0]
  111.                 dstImage[i, j] = color
  112.  
  113.         # Update the new layer
  114.         newLayer.flush()
  115.         newLayer.merge_shadow(True)
  116.         newLayer.update(0, 0, newLayer.width, newLayer.height)
  117.  
  118.         # Remove the old layer
  119.         img.remove_layer(layer)
  120.         newLayer.name = layerName
  121.  
  122.         # Resize the image to new size
  123.         img.resize(newLayer.width, newLayer.height, 0, 0)
  124.     except Exception as err:
  125.         gimp.message("Unexpected error: " + str(err))
  126.  
  127.     # Close the undo group
  128.     pdb.gimp_image_undo_group_end(img)
  129.  
  130.     # End progress
  131.     pdb.gimp_progress_end()
  132.  
  133. register(
  134.     "aniniscript",
  135.     "Aninimouse downscaling",
  136.     "Resizes the image by taking dominant colors in [X factor : Y factor] blocks",
  137.     "Dmitry Odintsov",
  138.     "MIT",
  139.     "2017",
  140.     "<Image>/Filters/Aninimouse/Downscaling",
  141.     "RGB, RGB*",
  142.     [
  143.         (PF_INT, "x_factor", "X factor", 8),
  144.         (PF_INT, "y_factor", "Y factor", 8)
  145.     ],
  146.     [],
  147.     aniniscript)
  148.  
  149. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement