Linux-Fan

Invert image colors

Jan 31st, 2012
132
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package test;
  2.  
  3. /*
  4.  * A simple example of how to invert/modify bitmaps with java.
  5.  *
  6.  * Copyright (C) 2012  Ma_Sys.ma
  7.  *
  8.  * This program is free software: you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation, either version 3 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20.  */
  21.  
  22. // Basic Imports that could be helpful
  23. import javax.imageio.*;
  24. import java.awt.*;
  25. import java.awt.image.*;
  26. import java.io.*;
  27. import java.lang.*;
  28. import java.lang.reflect.*;
  29. import java.util.*;
  30.  
  31. public class InvertColors {
  32.  
  33.     public static class LoopInverter extends DistributedLoopThread {
  34.  
  35.         private BufferedImage img;
  36.    
  37.         public LoopInverter(Integer start, Integer end, DistributedLoop ownerLoop) {
  38.             super(start, end, ownerLoop);
  39.         }
  40.        
  41.         public void pass(Object...data) {
  42.             img = (BufferedImage)data[0];
  43.         }
  44.  
  45.         protected void execLoop() {
  46.             int width = img.getWidth();
  47.             int j;
  48.             int[] line;
  49.             for(int i = START; i < END; i++) {
  50.                 // Get a single line of pixels
  51.                 line = img.getRGB(0, i, img.getWidth(), 1, null, 0, width);
  52.                 for(j = 0; j < line.length; j++) {
  53.                     // Actual inversion
  54.                     line[j] = 0xffffff ^ line[j];
  55.                 }
  56.                 // Store the pixels back into the image
  57.                 img.setRGB(0, i, width, 1, line, 0, width);
  58.             }
  59.         }
  60.  
  61.     }
  62.  
  63.     public static void main(String[] args) {
  64.         System.out.println("Invert Colors 1.0, Copyright (c) 2012 Ma_Sys.ma.");
  65.         System.out.println("For further info send an e-mail to Ma_Sys.ma@web.de.");
  66.         System.out.println();
  67.         if(args.length != 1) {
  68.             System.out.println("Usage: java test.InvertColors [image]");
  69.             System.exit(1);
  70.         }
  71.  
  72.         int extensionPosition = args[0].lastIndexOf('.');
  73.         if(extensionPosition == -1) {
  74.             System.out.println("Unable to determine input filetype.");
  75.             System.exit(1);
  76.         }
  77.  
  78.         // Read image data
  79.         BufferedImage img;
  80.         try {
  81.             img = ImageIO.read(new File(args[0]));
  82.         } catch(IOException ex) {
  83.             System.err.println("Unable to read image from " + args[0]);
  84.             ex.printStackTrace();
  85.             System.exit(2);
  86.             return; // "Variable might not have been initialized."
  87.         }
  88.  
  89.         long start = System.currentTimeMillis(); // Measure time
  90.  
  91.         // Invert all pixels using all processors
  92.         // See LoopInverter for the actual calculation
  93.         DistributedLoop loop;
  94.         try {
  95.             loop = new DistributedLoop(DistributedLoop.AUTO_DETERMINE_THREADS, 0, img.getHeight(), LoopInverter.class, null, null);
  96.         } catch(InstantiationException ex) {
  97.             System.err.println("Unable to create distributed loop.");
  98.             ex.printStackTrace();
  99.             System.exit(4);
  100.             return; // s. o.
  101.         }
  102.         loop.passArgumentsOnAll(img);
  103.         loop.startAll();
  104.  
  105.         System.out.println("Took " + (System.currentTimeMillis() - start) + " ms for the actual calculation.");
  106.  
  107.         // Write image data
  108.         try {
  109.             ImageIO.write(img, "png", new File(args[0].substring(0, extensionPosition) + "_inverted.png"));
  110.         } catch(IOException ex) {
  111.             System.err.println("Unable to write PNG image file.");
  112.             ex.printStackTrace();
  113.             System.exit(3);
  114.         }
  115.     }
  116.  
  117. }
  118.  
  119. // ---------------------------------------
  120. //  From the Tools Library in Version 2.0
  121. // ---------------------------------------
  122.  
  123. /**
  124.  * <p>
  125.  * Ermöglicht es, Rechenlast auf mehrere Kerne zu verteilen, indem eine
  126.  * Schleife in mehrere Teile aufgesplittet wird. Somit lassen sich Schleifen
  127.  * mit mehr Einträgen als Kerne vorhanden sind problemlos parallelisieren, wenn
  128.  * innerhalb der Schleife kein Ergebnis des vorherigen Durchganges benötigt wird.
  129.  * </p><p>
  130.  * Die Nutzung ist alles andere als einfach und soll deshalb am Beispiel gezeigt
  131.  * werden.
  132.  * </p><p>
  133.  * Alle Werte eines Arrays sollen initialisiert werden, indem
  134.  * komplexe Objekte erzeugt werden, deren Erstellung lange dauert:
  135.  * <br />
  136.  * <pre>
  137.     package ma.tools.concurrent;
  138.    
  139.     import ma.tools.concurrent.DistributedLoop;
  140.     import ma.tools.concurrent.DistributedLoopThread;
  141.    
  142.     public class DistributedLoopExample {
  143.    
  144.         private static int nr = 1;
  145.    
  146.         public DistributedLoopExample() {
  147.             super();
  148.             int objects = 32;
  149.             long start;
  150.            
  151.             // 1. Test mit normaler Schleife
  152.             start = System.currentTimeMillis();
  153.             ComplexObject[] allObjects = new ComplexObject[objects];
  154.             for(int i = 0; i < objects; i++) {
  155.                 allObjects[i] = new ComplexObject();
  156.             }
  157.             System.out.println("Normalerweise braucht man " + (System.currentTimeMillis() - start) + " ms zum Erstellen der Objekte.");
  158.            
  159.             // 2. Test mit verteilter Schleife
  160.             start = System.currentTimeMillis();
  161.             allObjects = new ComplexObject[objects];
  162.             DistributedLoop loop;
  163.             try {
  164.                 loop = new DistributedLoop(DistributedLoop.AUTO_DETERMINE_THREADS, 0, objects, CreatorInstance.class, null, this);
  165.             } catch(InstantiationException ex) {
  166.                 ex.printStackTrace();
  167.                 return;
  168.             }
  169.             // Wir wollen das Array nicht als mehrere Argumente übergeben
  170.             loop.passArgumentsOnAll((Object)allObjects);
  171.             loop.startAll();
  172.             System.out.println("Verteilt dauert es (nur?) " + (System.currentTimeMillis() - start) + " ms");
  173.         }
  174.        
  175.         public class CreatorInstance extends DistributedLoopThread {
  176.  
  177.             private ComplexObject[] allObjects;
  178.            
  179.             public CreatorInstance(Integer start, Integer end, DistributedLoop ownerLoop) {
  180.                 super(start, end, ownerLoop);
  181.             }
  182.            
  183.             protected void pass(Object...data) {
  184.                 allObjects = (ComplexObject[])data[0];
  185.             }
  186.  
  187.             protected void execLoop() {
  188.                 for(int i = START; i &lt; END; i++) {
  189.                     allObjects[i] = new ComplexObject();
  190.                 }
  191.             }
  192.            
  193.         }
  194.        
  195.         private class ComplexObject {
  196.        
  197.             public ComplexObject() {
  198.                 int cnr = nr++;
  199.                 System.out.println("Komplexes Objekt " + cnr + " erstellen...");
  200.                 // Zeit die es braucht um ein Objekt zu erstellen (hier künstlich verlangsamt)
  201.                 try {
  202.                     Thread.sleep(250);
  203.                 } catch(InterruptedException ex) {
  204.                     System.out.println("Komplexes Objekt " + cnr + ": Erstellung abgebrochen: " + ex.toString());
  205.                 }
  206.                 System.out.println("Komplexes Objekt " + cnr + " fertig.");
  207.             }
  208.         }
  209.    
  210.         public static void main(String[] args) {
  211.             new DistributedLoopExample();
  212.         }
  213.    
  214.     }
  215.  * </pre>
  216.  * <br />
  217.  * Wenn man die "künstlich verlängernden" Zeilen wegnimmt, sieht man
  218.  * sehr gut, dass es einen Overhead (auf dem Testsystem rund 3ms) durch
  219.  * die Paralelisierung gibt. Deshalb lohnt es sich nur bei der Erstellung
  220.  * von Objekten, die zusammen "relativ lange" brauchen, was auch schon bei
  221.  * z.B. 200 ms der Fall ist. Dadurch lohnt sich das Verteilte Rechnen an
  222.  * vielen Stellen.
  223.  * </p>
  224.  * <p>
  225.  * Hinweis #1: Bei Spiecherintensiven Anwendungen könnte es anders sein.
  226.  * Hier hilft es, beides zu testen.
  227.  * Das ist sehr einfach möglich, indem man dem Constructor als
  228.  * "preferredThreadCount" die Zahl 1 (keine parallelisierung)
  229.  * übergibt. Dies vermindert den Overhead aber nur sehr geringfügig.
  230.  * Wenn es knapp ist, sollte man eine "richtige" Schleife testen.
  231.  * </p><p>
  232.  * Hinweis #2: Rechenintensive Anwendungen profitieren eventuell vom
  233.  * Java Native Interface.
  234.  * </p><p>
  235.  * Hinweis #3: Optimieren Sie auch den Inhalt der Schleifen
  236.  * Sollte eigentlich klar sein.
  237.  * </p>
  238.  *
  239.  * @version 1.0.1
  240.  * @author Linux-Fan, Ma_Sys.ma
  241.  */
  242. class DistributedLoop {
  243.  
  244.     public static final int AUTO_DETERMINE_THREADS = -1;
  245.    
  246.     private DistributedLoopThread[] allThreads;
  247.    
  248.     private int readyThreads;
  249.    
  250.     private boolean started;
  251.    
  252.     private DistributedLoopUser owner;
  253.    
  254.     private ArrayList<Exception> theExceptions;
  255.    
  256.     public DistributedLoop(int preferredThreadCount, int lStart, int lEnd, Class<? extends DistributedLoopThread> threadClass, DistributedLoopUser owner, Object enclosing) throws InstantiationException {
  257.         super();
  258.         this.owner = owner;
  259.         theExceptions = new ArrayList<Exception>();
  260.         int realThreadCount = 0;
  261.         if(preferredThreadCount == AUTO_DETERMINE_THREADS) {
  262.             realThreadCount = Runtime.getRuntime().availableProcessors();
  263.         } else {
  264.             realThreadCount = preferredThreadCount;
  265.         }
  266.         int range = lEnd - lStart;
  267.         if(range < realThreadCount) {
  268.             realThreadCount = range;
  269.         }
  270.         allThreads = new DistributedLoopThread[realThreadCount];
  271.         readyThreads = 0;
  272.         started = false;
  273.         int perThread = range / allThreads.length;
  274.         for(int i = 0; i < allThreads.length; i++) {
  275.             final int cStart = lStart + perThread * i;
  276.             final int cEnd;
  277.             if(i == (allThreads.length - 1)) {
  278.                 cEnd = lEnd;
  279.             } else {
  280.                 cEnd = lStart + perThread * (i + 1);
  281.             }
  282.             try {
  283.                 if(enclosing == null) {
  284.                     allThreads[i] = threadClass.getConstructor(Integer.class, Integer.class, getClass()).newInstance(cStart, cEnd, this);
  285.                 } else {
  286.                     allThreads[i] = threadClass.getConstructor(enclosing.getClass(), Integer.class, Integer.class, getClass()).newInstance(enclosing, cStart, cEnd, this);
  287.                 }
  288.                 allThreads[i].setName("Distributed Loop Thread " + (i + 1));
  289.             } catch(Exception ex) {
  290.                 InstantiationException er = new InstantiationException("Unable to create distributed loop thread.");
  291.                 er.initCause(ex);
  292.                 throw er;
  293.             }
  294.         }
  295.     }
  296.    
  297.     public Iterator<Exception> startAll() {
  298.         if(!started) {
  299.             started = true;
  300.             for(int i = 0; i < allThreads.length; i++) {
  301.                 allThreads[i].start();
  302.             }
  303.             if(owner == null) {
  304.                 for(int i = 0; i < allThreads.length; i++) {
  305.                     try {
  306.                         allThreads[i].join();
  307.                     } catch(InterruptedException ex) {
  308.                         System.err.println("ma.tools.concurrent.DistributedLoop: Thread interrupted: " + ex.toString());
  309.                     } catch(IllegalThreadStateException ex) {
  310.                         System.err.println("ma.tools.concurrent.DistributedLoop: " + ex.toString());
  311.                     }
  312.                 }
  313.                 return theExceptions.iterator();
  314.             } else {
  315.                 return null;
  316.             }
  317.         } else {
  318.             throw new IllegalThreadStateException("Distributed loop was already started.");
  319.         }
  320.     }
  321.    
  322.     public void interruptAll() {
  323.         for(int i = 0; i < allThreads.length; i++) {
  324.             if(allThreads[i].isAlive()) {
  325.                 allThreads[i].interrupt();
  326.             }
  327.         }
  328.     }
  329.    
  330.     public Object[] callOnAll(Method m, Object...params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
  331.         Object[] allRets = new Object[allThreads.length];
  332.         for(int i = 0; i < allThreads.length; i++) {
  333.             allRets[i] = m.invoke(allThreads[i], params);
  334.         }
  335.         return allRets;
  336.     }
  337.    
  338.     public DistributedLoopThread[] getThreads() {
  339.         return allThreads;
  340.     }
  341.    
  342.     public void passArgumentsOnAll(Object...data) {
  343.         for(int i = 0; i < allThreads.length; i++) {
  344.             allThreads[i].pass(data);
  345.         }
  346.     }
  347.    
  348.     protected void readyCountUp() {
  349.         readyThreads++;
  350.         if(readyThreads == allThreads.length && owner != null) {
  351.             owner.distributedThreadsReady(theExceptions.toArray(new Exception[theExceptions.size()]));
  352.         }
  353.     }
  354.    
  355.     protected void passException(Exception ex) {
  356.         theExceptions.add(ex);
  357.     }
  358.    
  359.     public Iterator<Exception> getExceptions() {
  360.         return theExceptions.iterator();
  361.     }
  362.    
  363. }
  364.  
  365. abstract class DistributedLoopThread extends Thread {
  366.  
  367.     protected final int START;
  368.     protected final int END;
  369.     protected final DistributedLoop OWNER;
  370.    
  371.     public DistributedLoopThread(Integer start, Integer end, DistributedLoop ownerLoop) {
  372.         super();
  373.         this.START = start;
  374.         this.END   = end;
  375.         this.OWNER = ownerLoop;
  376.     }
  377.    
  378.     public void run() {
  379.         try {
  380.             execLoop();
  381.         } catch(Exception ex) {
  382.             OWNER.passException(ex);
  383.         }
  384.         OWNER.readyCountUp();
  385.     }
  386.    
  387.     protected void pass(@SuppressWarnings("unused") Object...data) {}
  388.    
  389.     protected abstract void execLoop() throws Exception;
  390.    
  391. }
  392.  
  393. /**
  394.  * <p>Veraltetes Interface.</p>
  395.  * <p>
  396.  * Kann genutzt werden, wenn man beim beenden alle Threads in
  397.  * eine andere Methode springen will.
  398.  * </p>
  399.  *
  400.  * @version 1.0.0.1
  401.  * @author Linux-Fan, Ma_Sys.ma
  402.  * @deprecated
  403.  *      Mittlerweile ist es möglich, dass {@link DistributedLoop#startAll()}
  404.  *      auf das Beenden der Threads wartet, ohne einen eigenen Wartethread zu
  405.  *      erzeugen.
  406.  */
  407. interface DistributedLoopUser {
  408.  
  409.     public void distributedThreadsReady(Exception[] passed);
  410.    
  411. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×