Created
November 11, 2015 14:08
-
-
Save gto76/9d4321b0ac23fc2c95f9 to your computer and use it in GitHub Desktop.
Scala bitmap filters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| exec scala "$0" "$@" | |
| !# | |
| import java.io.File | |
| import java.awt.image.BufferedImage | |
| import javax.imageio.ImageIO | |
| import javax.imageio.ImageTypeSpecifier | |
| import java.awt.image.DataBufferByte | |
| import java.awt.image.DataBufferInt | |
| import scala.runtime.ScalaRunTime._ | |
| import scala.util.Random | |
| object HelloWorld { | |
| val random = new Random() | |
| def main(args: Array[String]) { | |
| println("Hello, world! ") | |
| val firstArg = args.toList(0) | |
| println("First arg = " + firstArg) | |
| val fNameIn = firstArg | |
| val fIn = new File(fNameIn) | |
| val imgIn = convertToRgb(ImageIO.read(fIn)) | |
| val fNameOut = fNameIn.substring(0, fNameIn.lastIndexOf('.'))+"neg.png" | |
| val fOut = new File(fNameOut) | |
| val imgOut = monochrome(imgIn) | |
| testCompression(imgOut) | |
| ImageIO.write(imgOut, "png", fOut); | |
| } | |
| def testCompression(img: BufferedImage) { | |
| val pixels = (img.getRaster().getDataBuffer().asInstanceOf[DataBufferInt]).getData() | |
| printRasterAttributes(img) | |
| //compress | |
| val pix: List[Int] = List() | |
| var i = 0 | |
| for (p <- pixels) { | |
| val value = getGreen(p) | |
| /*if (value > 128) | |
| print("#") | |
| else | |
| print(" ")*/ | |
| print(value+" ") | |
| i = i + 1 | |
| if (i == img.getWidth) { | |
| i = 0 | |
| println() | |
| } | |
| } | |
| } | |
| def printRasterAttributes(img: BufferedImage) { | |
| val pixels = (img.getRaster().getDataBuffer().asInstanceOf[DataBufferInt]).getData() | |
| println("size = "+pixels.size) | |
| println("width = "+img.getWidth) | |
| println("height = "+img.getHeight) | |
| println("width * height = "+img.getWidth*img.getHeight) | |
| println("3 * width * height = "+img.getWidth*img.getHeight*3) | |
| } | |
| ///////////////// | |
| def convertToRgb(img: BufferedImage): BufferedImage = { | |
| val newImg = new BufferedImage(img.getWidth(), img.getHeight(), | |
| BufferedImage.TYPE_INT_RGB) | |
| newImg.getGraphics().drawImage(img, 0, 0, null) | |
| newImg | |
| } | |
| ///////////////// | |
| def noise(img: BufferedImage): BufferedImage = | |
| processImage(img, getNoise) | |
| def getNoise(rgb: Int): Int = | |
| changeAllColorsByPercent(rgb, random.nextDouble()) | |
| ///////////////// | |
| def negativ(img: BufferedImage) = processImage(img, getNegativ) | |
| def getNegativ(rgb: Int): Int = | |
| (0x0000ff - (rgb & 0x0000ff)) | | |
| (0x00ff00 - (rgb & 0x00ff00)) | | |
| (0xff0000 - (rgb & 0xff0000)) | |
| ///////////////// | |
| def monochrome(img: BufferedImage): BufferedImage = { | |
| def setGrayLevel1(rgb: Int) = assignToAll(getGrayLevel1(rgb)) | |
| processImage(img, setGrayLevel1) | |
| } | |
| ///////////////// | |
| def processImage(img: BufferedImage, filter: Int => Int): BufferedImage = { | |
| val imgOut = declareNewBufferedImage(img) | |
| for (i <- 0 to img.getHeight-1) { | |
| for (j <- 0 to img.getWidth-1) { | |
| val rgb = filter(img.getRGB(j, i)) | |
| imgOut.setRGB(j, i, rgb) | |
| } | |
| } | |
| imgOut | |
| } | |
| def changeAllColorsByPercent(rgb: Int, per: Double): Int = { | |
| (((rgb & 0x0000ff).asInstanceOf[Double] * per).asInstanceOf[Int] + (rgb & 0x0000ff)) | | |
| (((( (rgb & 0x00ff00) >> 8 ).asInstanceOf[Double] * per).asInstanceOf[Int] + ( (rgb & 0x00ff00) >> 8 ) )<< 8) | | |
| (((( (rgb & 0xff0000) >> 16 ).asInstanceOf[Double] * per).asInstanceOf[Int] + ( (rgb & 0xff0000) >> 16 ) ) << 16) | |
| } | |
| ////////// | |
| def getGrayLevel1(rgb: Int) : Int = { | |
| (getRed(rgb) * 0.3 + | |
| getGreen(rgb) * 0.59 + | |
| getBlue(rgb) * 0.11).asInstanceOf[Int] | |
| } | |
| def getGrayLevel2(rgb: Int) : Int = { | |
| ((rgb & 0x0000ff) + | |
| ((rgb & 0x00ff00) >> 8 ) + | |
| ((rgb & 0xff0000) >> 16 )) / 3 | |
| } | |
| def assignToAll(bw: Int): Int = { | |
| if (bw > 255) { | |
| return 0xffffff | |
| } else if (bw < 0) { | |
| return 0x000000 | |
| } else { | |
| return (bw) | (bw << 8) | (bw << 16) | |
| } | |
| } | |
| def getRed(rgb: Int): Int = (rgb & 0xff0000) >> 16 | |
| def getGreen(rgb: Int): Int = (rgb & 0x00ff00) >> 8 | |
| def getBlue(rgb: Int): Int = (rgb & 0x0000ff) | |
| def setRed(rgb: Int, red: Int): Int = { | |
| if (red <= 0) { | |
| return rgb & 0x00ffff; | |
| } | |
| else if (red >= 255) { | |
| return (rgb & 0xffffff) | (rgb | 0xff0000); | |
| } | |
| else { | |
| return (rgb & 0x00ffff) | (red << 16); | |
| } | |
| } | |
| def setGreen(rgb: Int, green: Int): Int = { | |
| if (green <= 0) { | |
| return rgb & 0xff00ff; | |
| } | |
| else if (green >= 255) { | |
| return (rgb & 0xffffff) | (rgb | 0x00ff00); | |
| } | |
| else { | |
| return (rgb & 0xff00ff) | (green << 8); | |
| } | |
| } | |
| def setBlue(rgb: Int, blue: Int): Int = { | |
| if (blue <= 0) { | |
| return rgb & 0xffff00; | |
| } | |
| else if (blue >= 255) { | |
| return (rgb & 0xffffff) | (rgb | 0x0000ff); | |
| } | |
| else { | |
| return (rgb & 0xffff00) | (blue); | |
| } | |
| } | |
| def printRGB(rgb: Int): Unit = { | |
| val red = getRed(rgb); | |
| val green = getGreen(rgb); | |
| val blue = getBlue(rgb); | |
| System.out.println(red + "\t" + green + "\t" + blue); | |
| } | |
| ////////// | |
| def declareNewBufferedImage(img: BufferedImage): BufferedImage = { | |
| val its = new ImageTypeSpecifier(img) | |
| new BufferedImage(img.getWidth(), | |
| img.getHeight(), | |
| its.getBufferedImageType()) | |
| } | |
| def declareNewBufferedImage(x: Int, y: Int): BufferedImage = | |
| new BufferedImage(x, y, BufferedImage.TYPE_INT_RGB) | |
| } | |
| HelloWorld.main(args) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment