QJCC homepage

biz.chitec.quarterback.swing
Class TinyImageEditor

java.lang.Object
  extended byjava.awt.Component
      extended byjava.awt.Container
          extended byjavax.swing.JComponent
              extended byjavax.swing.JPanel
                  extended bybiz.chitec.quarterback.swing.TinyImageEditor
All Implemented Interfaces:
javax.accessibility.Accessible, java.awt.image.ImageObserver, java.awt.MenuContainer, java.io.Serializable

public class TinyImageEditor
extends javax.swing.JPanel

Image editor for some basic operations: Cropping, scaling, changing format and compression level

TinyImageEditor features a scaling image presentation, some basic information about the image and its storing file and allows some basic operation to change them: Cropping to take only a part of the image, scaling to make the image smaller (or larger...), and changing storage type (PNG versus JPG) and JPG compression level, if applicable.

The widget is derived vom JPanel, so it can be inserted at almost every place in a dialog. An image is loaded into the editor by calling setImage(imagedata,lossyflag). The image data is taken verbatim from a file or any other source producing an image in JPG or PNG encoding. To get an editing result, call getImage(). To see whether any editing took place at all, call isEdited() and/or hook a listener onto the EDITED property.

TimeImageEditor creates internally a java.awt.Image from the given data. All operations are always performed on this representation and are therefore lossless, even if output is set to, say, JPG with a very low quality level. The editor shows the data in the selected quality level on screen, but keeps the lossless representation internally. The first place where this quality-decreased data shows up again programmatically is the getImage() method. Therefore, during editing, it is even possible to change JPG quality level in both directions. Undo always starts again with the data given through setImage().

Version:
$Id: b599eccae77725a4b8de0d5b6ef162fc3f6f5ce3 $
Author:
Dirk Hillbrecht 2004 Distributed under the terms of the GNU LGPL.
See Also:
Serialized Form

Nested Class Summary
 
Nested classes inherited from class javax.swing.JPanel
javax.swing.JPanel.AccessibleJPanel
 
Nested classes inherited from class javax.swing.JComponent
javax.swing.JComponent.AccessibleJComponent
 
Nested classes inherited from class java.awt.Container
java.awt.Container.AccessibleAWTContainer
 
Nested classes inherited from class java.awt.Component
java.awt.Component.AccessibleAWTComponent, java.awt.Component.BltBufferStrategy, java.awt.Component.FlipBufferStrategy
 
Field Summary
private  javax.swing.Box buttonbox
           
private  javax.swing.JButton cropbutton
           
private  boolean edited
           
private static Hotkeys hotkeys
           
private  javax.swing.JLabel imageinfolabel
           
private  javax.swing.JButton jqbutton
           
private  javax.swing.JRadioButton losslessbutton
           
private  java.awt.image.BufferedImage losslessimage
           
private  boolean lossy
           
private  javax.swing.JRadioButton lossybutton
           
private  java.awt.image.BufferedImage lossyimage
           
private  float lossyquality
           
private  byte[] originalbytes
           
private  boolean originallossy
           
private static java.text.NumberFormat percentformatter
           
private  java.util.ResourceBundle rb
           
private  javax.swing.JButton rescalebutton
           
private  float resizefactor
           
private  byte[] resultbytes
           
private  ScalingImagePane sip
           
private  javax.swing.JButton undobutton
           
private  int xsize
           
private  int ysize
           
 
Fields inherited from class javax.swing.JPanel
 
Fields inherited from class javax.swing.JComponent
accessibleContext, listenerList, TOOL_TIP_TEXT_KEY, ui, UNDEFINED_CONDITION, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, WHEN_FOCUSED, WHEN_IN_FOCUSED_WINDOW
 
Fields inherited from class java.awt.Container
 
Fields inherited from class java.awt.Component
BOTTOM_ALIGNMENT, CENTER_ALIGNMENT, LEFT_ALIGNMENT, RIGHT_ALIGNMENT, TOP_ALIGNMENT
 
Fields inherited from interface java.awt.image.ImageObserver
ABORT, ALLBITS, ERROR, FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, WIDTH
 
Constructor Summary
TinyImageEditor()
           
 
Method Summary
 void clear()
           
private  void createAndShowResultBytes()
          Creates the result byte stream and shows the result.
private  void createResultBytes()
          Creates the result byte stream and the lossy image from the lossless image.
 byte[] getImage()
          Returns the edited image.
 boolean isEdited()
          Returns whether the current editor content is edited in any way.
 boolean isLossy()
          Returns whether the result byte stream is lossy or not.
private  void processCrop()
          Performs the crop operation The rectangle to be left over from the crop operation is taken from the image pane.
private  void processRescale(int newx, int newy)
          Performs the rescale operation.
private  void restoreImage()
          Restore the complete editor from the originally given image.
private  void setEdited(boolean newval)
          Set internally whether something has been edited compared to the setImage() state.
 void setImage(byte[] imagedatax, boolean lossyx)
          Sets the image to work on, can be called from any thread.
private  void showImage()
          Called after any changes to the image objects have been performed.
private  void showJpegQualityDialog()
          Shows the dialog to change the JPEG compression level.
private  void showRescaleDialog()
          Shows the dialog to rescale the image.
 
Methods inherited from class javax.swing.JPanel
getAccessibleContext, getUI, getUIClassID, paramString, setUI, updateUI
 
Methods inherited from class javax.swing.JComponent
addAncestorListener, addNotify, addPropertyChangeListener, addPropertyChangeListener, addVetoableChangeListener, computeVisibleRect, contains, createToolTip, disable, enable, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, fireVetoableChange, getActionForKeyStroke, getActionMap, getAlignmentX, getAlignmentY, getAncestorListeners, getAutoscrolls, getBorder, getBounds, getClientProperty, getComponentGraphics, getConditionForKeyStroke, getDebugGraphicsOptions, getDefaultLocale, getGraphics, getHeight, getInputMap, getInputMap, getInputVerifier, getInsets, getInsets, getListeners, getLocation, getMaximumSize, getMinimumSize, getNextFocusableComponent, getPreferredSize, getPropertyChangeListeners, getPropertyChangeListeners, getRegisteredKeyStrokes, getRootPane, getSize, getToolTipLocation, getToolTipText, getToolTipText, getTopLevelAncestor, getTransferHandler, getVerifyInputWhenFocusTarget, getVetoableChangeListeners, getVisibleRect, getWidth, getX, getY, grabFocus, isDoubleBuffered, isLightweightComponent, isManagingFocus, isMaximumSizeSet, isMinimumSizeSet, isOpaque, isOptimizedDrawingEnabled, isPaintingTile, isPreferredSizeSet, isRequestFocusEnabled, isValidateRoot, paint, paintBorder, paintChildren, paintComponent, paintImmediately, paintImmediately, print, printAll, printBorder, printChildren, printComponent, processComponentKeyEvent, processKeyBinding, processKeyEvent, processMouseMotionEvent, putClientProperty, registerKeyboardAction, registerKeyboardAction, removeAncestorListener, removeNotify, removePropertyChangeListener, removePropertyChangeListener, removeVetoableChangeListener, repaint, repaint, requestDefaultFocus, requestFocus, requestFocus, requestFocusInWindow, requestFocusInWindow, resetKeyboardActions, reshape, revalidate, scrollRectToVisible, setActionMap, setAlignmentX, setAlignmentY, setAutoscrolls, setBackground, setBorder, setDebugGraphicsOptions, setDefaultLocale, setDoubleBuffered, setEnabled, setFont, setForeground, setInputMap, setInputVerifier, setMaximumSize, setMinimumSize, setNextFocusableComponent, setOpaque, setPreferredSize, setRequestFocusEnabled, setToolTipText, setTransferHandler, setUI, setVerifyInputWhenFocusTarget, setVisible, unregisterKeyboardAction, update
 
Methods inherited from class java.awt.Container
add, add, add, add, add, addContainerListener, addImpl, applyComponentOrientation, areFocusTraversalKeysSet, countComponents, deliverEvent, doLayout, findComponentAt, findComponentAt, getComponent, getComponentAt, getComponentAt, getComponentCount, getComponents, getContainerListeners, getFocusTraversalKeys, getFocusTraversalPolicy, getLayout, insets, invalidate, isAncestorOf, isFocusCycleRoot, isFocusCycleRoot, isFocusTraversalPolicySet, layout, list, list, locate, minimumSize, paintComponents, preferredSize, printComponents, processContainerEvent, processEvent, remove, remove, removeAll, removeContainerListener, setFocusCycleRoot, setFocusTraversalKeys, setFocusTraversalPolicy, setLayout, transferFocusBackward, transferFocusDownCycle, validate, validateTree
 
Methods inherited from class java.awt.Component
action, add, addComponentListener, addFocusListener, addHierarchyBoundsListener, addHierarchyListener, addInputMethodListener, addKeyListener, addMouseListener, addMouseMotionListener, addMouseWheelListener, bounds, checkImage, checkImage, coalesceEvents, contains, createImage, createImage, createVolatileImage, createVolatileImage, disableEvents, dispatchEvent, enable, enableEvents, enableInputMethods, getBackground, getBounds, getColorModel, getComponentListeners, getComponentOrientation, getCursor, getDropTarget, getFocusCycleRootAncestor, getFocusListeners, getFocusTraversalKeysEnabled, getFont, getFontMetrics, getForeground, getGraphicsConfiguration, getHierarchyBoundsListeners, getHierarchyListeners, getIgnoreRepaint, getInputContext, getInputMethodListeners, getInputMethodRequests, getKeyListeners, getLocale, getLocation, getLocationOnScreen, getMouseListeners, getMouseMotionListeners, getMouseWheelListeners, getName, getParent, getPeer, getSize, getToolkit, getTreeLock, gotFocus, handleEvent, hasFocus, hide, imageUpdate, inside, isBackgroundSet, isCursorSet, isDisplayable, isEnabled, isFocusable, isFocusOwner, isFocusTraversable, isFontSet, isForegroundSet, isLightweight, isShowing, isValid, isVisible, keyDown, keyUp, list, list, list, location, lostFocus, mouseDown, mouseDrag, mouseEnter, mouseExit, mouseMove, mouseUp, move, nextFocus, paintAll, postEvent, prepareImage, prepareImage, processComponentEvent, processFocusEvent, processHierarchyBoundsEvent, processHierarchyEvent, processInputMethodEvent, processMouseEvent, processMouseWheelEvent, remove, removeComponentListener, removeFocusListener, removeHierarchyBoundsListener, removeHierarchyListener, removeInputMethodListener, removeKeyListener, removeMouseListener, removeMouseMotionListener, removeMouseWheelListener, repaint, repaint, repaint, resize, resize, setBounds, setBounds, setComponentOrientation, setCursor, setDropTarget, setFocusable, setFocusTraversalKeysEnabled, setIgnoreRepaint, setLocale, setLocation, setLocation, setName, setSize, setSize, show, show, size, toString, transferFocus, transferFocusUpCycle
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

hotkeys

private static Hotkeys hotkeys

percentformatter

private static final java.text.NumberFormat percentformatter

rb

private java.util.ResourceBundle rb

sip

private ScalingImagePane sip

rescalebutton

private javax.swing.JButton rescalebutton

cropbutton

private javax.swing.JButton cropbutton

jqbutton

private javax.swing.JButton jqbutton

undobutton

private javax.swing.JButton undobutton

lossybutton

private javax.swing.JRadioButton lossybutton

losslessbutton

private javax.swing.JRadioButton losslessbutton

imageinfolabel

private javax.swing.JLabel imageinfolabel

buttonbox

private javax.swing.Box buttonbox

originalbytes

private byte[] originalbytes

losslessimage

private java.awt.image.BufferedImage losslessimage

lossyimage

private java.awt.image.BufferedImage lossyimage

resultbytes

private byte[] resultbytes

originallossy

private boolean originallossy

lossy

private boolean lossy

edited

private boolean edited

xsize

private int xsize

ysize

private int ysize

resizefactor

private float resizefactor

lossyquality

private float lossyquality
Constructor Detail

TinyImageEditor

public TinyImageEditor()
Method Detail

clear

public void clear()

setImage

public void setImage(byte[] imagedatax,
                     boolean lossyx)
Sets the image to work on, can be called from any thread. The image is shown in the editor, everything is reset. The method switches internally to the event dispatching thread, so it can be called from any thread.

Parameters:
imagedatax - The image data as byte stream (e.g. the contents of a JPG file on disk)
lossyx - Flag whether the image data should be handled as lossy (true) or lossless (false)

getImage

public byte[] getImage()
Returns the edited image. If no editing has taken place, the original byte stream is returned. Otherwise, a reencoded stream is returned containing a new image composed accordingly to lossy settings and the JPG compression level. The returned data can be handled as any byte stream representing an image, e.g. written verbatim to a disk file.

Returns:
Byte stream representing an image in JPG or PNG encoding

isLossy

public boolean isLossy()
Returns whether the result byte stream is lossy or not. This can change during editing.


isEdited

public boolean isEdited()
Returns whether the current editor content is edited in any way. This returns false directly after setting the content and after "Undo" has been pressed.

Returns:
Flag whether something has changed

setEdited

private void setEdited(boolean newval)
Set internally whether something has been edited compared to the setImage() state. This method is only called internally and therefore private. Beside saving the new "edited" state, it controls also the "undo" button and fires a property change event if necessary. To make TinyImageEditor operating correctly, the "edited" flag must always be changed through this method.

Parameters:
newval - The new "edited" state.

restoreImage

private void restoreImage()
Restore the complete editor from the originally given image. Called internally either at the end of setImage() or to perform the undo operation.


showImage

private void showImage()
Called after any changes to the image objects have been performed. Sorts out whether lossless or lossy image should be taken, shows picture and size in output frame. Note that image fields and byte streams have to be initialized correctly before this method is called.


createResultBytes

private void createResultBytes()
Creates the result byte stream and the lossy image from the lossless image. In lossless mode, a PNG byte stream is created from the lossless image and the lossy image is set equal to the lossless image. In lossy mode, a JPG byte stream is created from the lossless image and the lossy image is derived from that byte stream. Mode and lossy quality are taken from the global fields. In case of any problems, empty stream and image are created.


createAndShowResultBytes

private void createAndShowResultBytes()
Creates the result byte stream and shows the result.


showJpegQualityDialog

private void showJpegQualityDialog()
Shows the dialog to change the JPEG compression level. Changing the level is always directly shown on screen. Further changes on the picture, however, do always work on the lossless data.


showRescaleDialog

private void showRescaleDialog()
Shows the dialog to rescale the image. Rescaling is done directly in the lossless image. On screen, we see the lossy image, however, if lossy imaging is wanted.


processRescale

private void processRescale(int newx,
                            int newy)
Performs the rescale operation. Rescaling is always performed using the "smooth" algorithm. The result overwrites the current lossless image object.

Parameters:
newx - New width of the image
newy - New height of the image

processCrop

private void processCrop()
Performs the crop operation The rectangle to be left over from the crop operation is taken from the image pane. Cropping is performed with the standard java.awt.Image capabilities. The result overwrites the current lossless image object.


QJCC homepage