Advertisement
jules0707

scalashop

Feb 23rd, 2017
263
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 2.90 KB | None | 0 0
  1. import common._
  2.  
  3. package object scalashop {
  4.  
  5.   /** The value of every pixel is represented as a 32 bit integer. */
  6.   type RGBA = Int
  7.  
  8.   /** Returns the red component. */
  9.   def red(c: RGBA): Int = (0xff000000 & c) >>> 24
  10.  
  11.   /** Returns the green component. */
  12.   def green(c: RGBA): Int = (0x00ff0000 & c) >>> 16
  13.  
  14.   /** Returns the blue component. */
  15.   def blue(c: RGBA): Int = (0x0000ff00 & c) >>> 8
  16.  
  17.   /** Returns the alpha component. */
  18.   def alpha(c: RGBA): Int = (0x000000ff & c) >>> 0
  19.  
  20.   /** Used to create an RGBA value from separate components. */
  21.   def rgba(r: Int, g: Int, b: Int, a: Int): RGBA = {
  22.     (r << 24) | (g << 16) | (b << 8) | (a << 0)
  23.   }
  24.  
  25.   /** Restricts the integer into the specified range. */
  26.   def clamp(v: Int, min: Int, max: Int): Int = {
  27.     if (v < min) min
  28.     else if (v > max) max
  29.     else v
  30.   }
  31.  
  32.   /** Image is a two-dimensional matrix of pixel values. */
  33.   class Img(val width: Int, val height: Int, private val data: Array[RGBA]) {
  34.     def this(w: Int, h: Int) = this(w, h, new Array(w * h))
  35.     def apply(x: Int, y: Int): RGBA = data(y * width + x)
  36.     def update(x: Int, y: Int, c: RGBA): Unit = data(y * width + x) = c
  37.   }
  38.  
  39.   /** Computes the blurred RGBA value of a single pixel of the input image. */
  40.   def boxBlurKernel(src: Img, x: Int, y: Int, radius: Int): RGBA = {
  41.    
  42.  
  43.     /* credits to https://github.com/dnc1994
  44.      var (r, g, b, a) = (0, 0, 0, 0)
  45.  
  46.         val xMin = clamp(x - radius, 0, src.width - 1)
  47.         val xMax = clamp(x + radius, 0, src.width - 1)
  48.         val yMin = clamp(y - radius, 0, src.height - 1)
  49.         val yMax = clamp(y + radius, 0, src.height - 1)
  50.  
  51.         var (i, j, n) = (xMin, yMin, 0.0)
  52.  
  53.         while (i <= xMax) {
  54.             while (j <= yMax) {
  55.                 val p = src.apply(i, j)
  56.                 r = r + red(p)
  57.                 g = g + green(p)
  58.                 b = b + blue(p)
  59.                 a = a + alpha(p)
  60.                 n += 1
  61.                 j += 1
  62.             }
  63.             j = yMin
  64.             i += 1
  65.         }
  66.         rgba((r / n).toInt, (g / n).toInt, (b / n).toInt, (a / n).toInt)
  67.   */  
  68.    
  69. /* Credits goes to https://github.com/TomLous but speed efficiency is an issue as nested ranges inside for comprehension desugars to nested while loops. For more visit:
  70. https://www.coursera.org/learn/parprog1/discussions/forums/axN_EOpJEeWfwAohgaM63Q/threads/wRg6aS7-Eea3ThLvjcf5Xw
  71. */
  72.     val pixels = {
  73.       for (
  74.         i <- -radius to radius;
  75.         j <- -radius to radius
  76.       ) yield (clamp(x + i, 0, src.width - 1), clamp(y + j, 0, src.height - 1))
  77.     }.distinct.map({
  78.       case (x, y) =>
  79.         val pixel = src(x, y)
  80.         (red(pixel), green(pixel), blue(pixel), alpha(pixel))
  81.     })
  82.  
  83.     rgba(
  84.       pixels.map(_._1).sum / pixels.length,
  85.       pixels.map(_._2).sum / pixels.length,
  86.       pixels.map(_._3).sum / pixels.length,
  87.       pixels.map(_._4).sum / pixels.length)
  88.   }
  89. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement