org.refcodes.graphical.GraphicalUtility Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of refcodes-graphical Show documentation
Show all versions of refcodes-graphical Show documentation
Artifact for graphical issues regarding RGB, pixel, fonts, and other stuff (utility).
The newest version!
// /////////////////////////////////////////////////////////////////////////////
// REFCODES.ORG
// =============================================================================
// This code is copyright (c) by Siegfried Steiner, Munich, Germany, distributed
// on an "AS IS" BASIS WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, and licen-
// sed under the following (see "http://en.wikipedia.org/wiki/Multi-licensing")
// licenses:
// =============================================================================
// GNU General Public License, v3.0 ("http://www.gnu.org/licenses/gpl-3.0.html")
// together with the GPL linking exception applied; as being applied by the GNU
// Classpath ("http://www.gnu.org/software/classpath/license.html")
// =============================================================================
// Apache License, v2.0 ("http://www.apache.org/licenses/TEXT-2.0")
// =============================================================================
// Please contact the copyright holding author(s) of the software artifacts in
// question for licensing issues not being covered by the above listed licenses,
// also regarding commercial licensing models or regarding the compatibility
// with other open source licenses.
// /////////////////////////////////////////////////////////////////////////////
package org.refcodes.graphical;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
/**
* The Class GraphicalUtility.
*/
public final class GraphicalUtility {
// /////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS:
// /////////////////////////////////////////////////////////////////////////
/**
* Private empty constructor to prevent instantiation as of being a utility
* with just static public methods.
*/
private GraphicalUtility() {}
// /////////////////////////////////////////////////////////////////////////
// METHODS:
// /////////////////////////////////////////////////////////////////////////
/**
* Converts the given RGB value to a gray scale value by averaging the red,
* green and blue portions of the RGB value.
*
* @param aRgbValue The RGB value to be converted to a grays scale value.
*
* @return The gray scale value from the RGB value.
*/
public static int toGray( int aRgbValue ) {
return ( ( toRed( aRgbValue ) + toGreen( aRgbValue ) + toBlue( aRgbValue ) ) / 3 );
}
/**
* Combines the alpha, red, green and blue values to an RGB value.
*
* @param aAlpha The alpha value to use.
* @param aRed The red value to use.
* @param aGreen The green value to use.
* @param aBlue The blue value to use.
*
* @return The according RGB value from the alpha, red, green and blue
* values.
*/
public static int toRgb( int aAlpha, int aRed, int aGreen, int aBlue ) {
return ( aAlpha << 24 ) + ( aRed << 16 ) + ( aGreen << 8 ) + aBlue;
}
/**
* Retrieves the alpha portion of the provided RGB value.
*
* @param aRgbValue The RGB value from which to retrieve the alpha portion.
*
* @return The alpha portion from the according RGB value.
*/
public static int toAlpha( int aRgbValue ) {
return ( aRgbValue >> 24 ) & 0xFF;
}
/**
* Retrieves the red portion of the provided RGB value.
*
* @param aRgbValue The RGB value from which to retrieve the red portion.
*
* @return The red portion from the according RGB value.
*/
public static int toRed( int aRgbValue ) {
return ( aRgbValue >> 16 ) & 0xFF;
}
/**
* Retrieves the green portion of the provided RGB value.
*
* @param aRgbValue The RGB value from which to retrieve the green portion.
*
* @return The green portion from the according RGB value.
*/
public static int toGreen( int aRgbValue ) {
return ( aRgbValue >> 8 ) & 0xFF;
}
/**
* Retrieves the blue portion of the provided RGB value.
*
* @param aRgbValue The RGB value from which to retrieve the blue portion.
*
* @return The blue portion from the according RGB value.
*/
public static int toBlue( int aRgbValue ) {
return aRgbValue & 0xFF;
}
/**
* Tries to determine the font size for the given font name and font style
* for the given text to fit into the given width (pixels). In case the font
* size cannot be detected to make the given text fit exactly into the given
* width, then the biggest font size is used with which the text still fits
* into the given width. The width of the text will not exceed the given
* width.
*
* @param aText The text to fit into the given (pixel) width.
* @param aWidth The (pixel) width into which the given text is to fit.
* @param aFontName The font name to use for determining the correct font
* size.
* @param aFontStyle The font style to be used
*
* @return the font
*/
public static Font getAwtFont( String aText, int aWidth, String aFontName, int aFontStyle ) {
int theFontSize = 5;
Font eFont;
Font ePreviousFont = null;
int eWidth = 0;
do {
eFont = new Font( aFontName, aFontStyle, theFontSize );
eWidth = toPixelWidth( aText, eFont );
if ( eWidth < aWidth ) {
ePreviousFont = eFont;
}
theFontSize++;
} while ( eWidth < aWidth );
if ( eWidth == aWidth ) {
return eFont;
}
if ( ePreviousFont == null ) {
throw new IllegalArgumentException( "Unable to determine the font size for font \"" + aFontName + "\" with style \"" + aFontStyle + "\" for text \"" + aText + "\" to fit into a width of y <" + aWidth + "> as the smallest font already exceeds this width with width <" + eWidth + ">." );
}
return ePreviousFont;
}
/**
* Loads an SVG image from the given resource (URL) and transforms it to the
* required dimension (as SVG is vector graphics and we need a pixel
* representation). You can get a resource something like below:
* "MyClass.class.getResource( "/chess/qlt_queen_light_transparent.svg" );"
*
* @param aText the text
* @param aFont the font
*
* @return The image with the given dimensions transformed from the provided
* SVG resource.
*/
// public static Image fromSvgResource( URL aResource, int aWidth, int
// aHeight ) throws FileNotFoundException, TranscoderException,
// URISyntaxException {
// return fromSvgFile( new File( aResource.toURI() ), aWidth, aHeight );
// }
/**
* Loads an SVG image from the given file and transforms it to the required
* dimension (as SVG is vector graphics and we need a pixel representation).
*
* @param aFile The file from which to load the SVG file.
* @param aWidth The width in pixels of the loaded image.
* @param aHeight The height in pixels of the loaded image.
*
* @return The image with the given dimensions transformed from the provided
* SVG file.
*/
// public static Image fromSvgFile( File aFile, int aWidth, int aHeight )
// throws FileNotFoundException, TranscoderException {
// return fromSvgReader( new FileReader( aFile ), aWidth, aHeight );
// }
/**
* Loads an SVG image from the given string and transforms it to the
* required dimension (as SVG is vector graphics and we need a pixel
* representation).
*
* @param aSvg The SVG text from which to load the SVG file.
* @param aWidth The width in pixels of the loaded image.
* @param aHeight The height in pixels of the loaded image.
*
* @return The image with the given dimensions transformed from the provided
* SVG file.
*/
// public static Image fromSvg( String aSvg, int aWidth, int aHeight )
// throws TranscoderException {
// CustomTranscoder theTranscoder = new CustomTranscoder();
// theTranscoder.addTranscodingHint( PNGTranscoder.KEY_WIDTH, (float) aWidth
// );
// theTranscoder.addTranscodingHint( PNGTranscoder.KEY_HEIGHT, (float)
// aHeight );
// TranscoderInput theInput = new TranscoderInput( aSvg );
// theTranscoder.transcode( theInput, null );
// return SwingFXUtils.toFXImage( theTranscoder.getImage(), null );
// }
/**
* Loads an SVG image from the given reader and transforms it to the
* required dimension (as SVG is vector graphics and we need a pixel
* representation).
*
* @param aReader The reader from which to load the SVG file.
* @param aWidth The width in pixels of the loaded image.
* @param aHeight The height in pixels of the loaded image.
*
* @return The image with the given dimensions transformed from the provided
* SVG file.
*/
// public static Image fromSvgStream( InputStream aInputStream, int aWidth,
// int aHeight ) throws TranscoderException {
// return fromSvgReader( new BufferedReader(new
// InputStreamReader(aInputStream)), aWidth, aHeight );
// }
/**
* Loads an SVG image from the given reader and transforms it to the
* required dimension (as SVG is vector graphics and we need a pixel
* representation).
*
* @param aReader The reader from which to load the SVG file.
* @param aWidth The width in pixels of the loaded image.
* @param aHeight The height in pixels of the loaded image.
*
* @return The image with the given dimensions transformed from the provided
* SVG file.
*/
// public static Image fromSvgReader( Reader aReader, int aWidth, int
// aHeight ) throws TranscoderException {
// CustomTranscoder theTranscoder = new CustomTranscoder();
// theTranscoder.addTranscodingHint( PNGTranscoder.KEY_WIDTH, (float) aWidth
// );
// theTranscoder.addTranscodingHint( PNGTranscoder.KEY_HEIGHT, (float)
// aHeight );
// TranscoderInput theInput = new TranscoderInput( aReader );
// theTranscoder.transcode( theInput, null );
// return SwingFXUtils.toFXImage( theTranscoder.getImage(), null );
// }
// /////////////////////////////////////////////////////////////////////////
// HELPER:
// /////////////////////////////////////////////////////////////////////////
/**
* Truncates the not set pixels on the left and on the right and determines
* the width of the given text with the provided font without the truncated
* pixels. Unfortunately the {@link FontMetrics#stringWidth(String)} method
* regards some left and some right "border" of the text even though there
* are none pixels set for the text there.
*
* @param aText The text for which to determine the real truncated width.
* @param aFont The font to use to determine the real truncated width.
*
* @return The real truncated width.
*/
private static int toPixelWidth( String aText, Font aFont ) {
// int theImageType = BufferedImage.TYPE_USHORT_GRAY;
// BufferedImage theImage = new BufferedImage( 1, 1, theImageType );
final int theImageType = BufferedImage.TYPE_USHORT_GRAY;
BufferedImage theImage = new BufferedImage( 1, 1, theImageType );
Graphics theGraphics = theImage.getGraphics();
// Graphics theGraphics;
// try {
// theGraphics = theImage.getGraphics();
// }
//
// catch ( AWTError e1 ) {
// try {
// String theBefore = SystemProperty.JAVA_AWT_HEADLESS.getValue();
// SystemProperty.JAVA_AWT_HEADLESS.setValue( "true" );
// theGraphics = theImage.getGraphics();
// System.setProperty( "java.awt.headless", theBefore );
// }
// catch ( Exception e2 ) {
// throw e1;
// }
// }
theGraphics.setFont( aFont );
final FontMetrics theFontMetrics = theGraphics.getFontMetrics();
final int theWidth = theFontMetrics.stringWidth( aText );
final int theHeight = theFontMetrics.getHeight();
theImage = new BufferedImage( theWidth, theHeight, theImageType );
theGraphics = theImage.getGraphics();
theGraphics.setFont( aFont );
final Graphics2D theGraphics2d = (Graphics2D) theGraphics;
theGraphics2d.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON );
theGraphics2d.drawString( aText, 0, theHeight );
int theTrimBegin = 0;
int theTrimEnd = theWidth;
int eGray;
leftOut: for ( int x = 0; x < theWidth; x++ ) {
for ( int y = 0; y < theHeight; y++ ) {
eGray = toGray( theImage.getRGB( x, y ) );
if ( eGray != 0 ) {
break leftOut;
}
}
theTrimBegin = x + 1;
}
rightOut: for ( int x = theWidth - 1; x >= 0; x-- ) {
for ( int y = 0; y < theHeight; y++ ) {
eGray = toGray( theImage.getRGB( x, y ) );
if ( eGray != 0 ) {
break rightOut;
}
}
theTrimEnd = x - 1;
}
final int theTrimmed = theTrimEnd - theTrimBegin - 1;
return theTrimmed;
}
}