001 /* 002 * Brightness 003 * 004 * Copyright (c) 2001, 2002, 2003 Marco Schmidt. 005 * All rights reserved. 006 */ 007 008 package net.sourceforge.jiu.color.adjustment; 009 010 import net.sourceforge.jiu.data.GrayIntegerImage; 011 import net.sourceforge.jiu.data.IntegerImage; 012 import net.sourceforge.jiu.data.Palette; 013 import net.sourceforge.jiu.data.Paletted8Image; 014 import net.sourceforge.jiu.data.RGBIntegerImage; 015 import net.sourceforge.jiu.ops.LookupTableOperation; 016 import net.sourceforge.jiu.ops.MissingParameterException; 017 import net.sourceforge.jiu.ops.WrongParameterException; 018 019 /** 020 * Adjusts the brightness of an image. 021 * The amount of adjustment is given to the constructor as a percentage value between -100 and 100. 022 * -100 will make the resulting image black, 0 will leave it unchanged, 100 will make it white. 023 * <h3>Usage example</h3> 024 * This code snippet will increase <code>image</code>'s brightness by 30 percent. 025 * <pre> 026 * Brightness brightness = new Brightness(); 027 * brightness.setInputImage(image); 028 * brightness.setBrightness(30); 029 * brightness.process(); 030 * PixelImage adjustedImage = brightness.getOutputImage(); 031 * </pre> 032 * @author Marco Schmidt 033 */ 034 public class Brightness extends LookupTableOperation 035 { 036 private int brightness; 037 038 /** 039 * Creates a lookup table that holds all new values for samples 0 to 040 * numSamples - 1. 041 */ 042 private int[] createLookupTable(int numSamples, int brightness) 043 { 044 if (brightness < -100 || brightness > 100) 045 { 046 return null; 047 } 048 int[] result = new int[numSamples]; 049 final int MAX = numSamples - 1; 050 final float MID = MAX / 2.0f; 051 for (int i = 0; i < numSamples; i++) 052 { 053 if (brightness < 0) 054 { 055 result[i] = (int)((float)i * (100.0f + brightness) / 100.0f); 056 } 057 else 058 { 059 result[i] = (int)(i + (MAX - i) * brightness / 100.0f); 060 } 061 } 062 return result; 063 } 064 065 private void process(Paletted8Image in, Paletted8Image out) 066 { 067 if (out == null) 068 { 069 out = (Paletted8Image)in.createCompatibleImage(in.getWidth(), in.getHeight()); 070 } 071 Palette palette = out.getPalette(); 072 int numSamples = palette.getMaxValue() + 1; 073 final int[] LUT = createLookupTable(numSamples, brightness); 074 for (int c = 0; c < 3; c++) 075 { 076 for (int i = 0; i < palette.getNumEntries(); i++) 077 { 078 palette.putSample(c, i, LUT[palette.getSample(c, i)]); 079 } 080 } 081 for (int y = 0; y < in.getHeight(); y++) 082 { 083 for (int x = 0; x < in.getWidth(); x++) 084 { 085 out.putSample(0, x, y, in.getSample(0, x, y)); 086 } 087 setProgress(y, in.getHeight()); 088 } 089 setOutputImage(out); 090 } 091 092 public void process() throws 093 MissingParameterException, 094 WrongParameterException 095 { 096 prepareImages(); 097 IntegerImage in = (IntegerImage)getInputImage(); 098 if (in instanceof GrayIntegerImage || in instanceof RGBIntegerImage) 099 { 100 setNumTables(in.getNumChannels()); 101 for (int channelIndex = 0; channelIndex < in.getNumChannels(); channelIndex++) 102 { 103 setTable(channelIndex, createLookupTable(in.getMaxSample(channelIndex) + 1, brightness)); 104 } 105 super.process(); 106 } 107 else 108 if (in instanceof Paletted8Image) 109 { 110 process((Paletted8Image)in, (Paletted8Image)getOutputImage()); 111 } 112 else 113 { 114 throw new WrongParameterException("Brightness operation cannot operate on input image type: " + in.getClass()); 115 } 116 } 117 118 /** 119 * Sets the brightness adjustment value in percent (between -100 and 100). 120 * @param newBrightness the amount of change to be applied to the brightness of the input image 121 * @throws IllegalArgumentException if the argument is smaller than -100 or larger than 100 122 */ 123 public void setBrightness(int newBrightness) 124 { 125 if (newBrightness < -100) 126 { 127 throw new IllegalArgumentException("Brightness must be at least -100: " + newBrightness); 128 } 129 if (newBrightness > 100) 130 { 131 throw new IllegalArgumentException("Brightness must be at most 100: " + newBrightness); 132 } 133 brightness = newBrightness; 134 } 135 }