package org.dazeend.harmonium.music;
import java.applet.Applet;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import org.blinkenlights.jid3.ID3Exception;
import org.blinkenlights.jid3.v1.ID3V1Tag;
import org.blinkenlights.jid3.v1.ID3V1_1Tag;
import org.blinkenlights.jid3.v2.APICID3V2Frame;
import org.blinkenlights.jid3.v2.ID3V2_3_0Tag;
import org.dazeend.harmonium.FactoryPreferences;
import org.dazeend.harmonium.Harmonium;
import org.dazeend.harmonium.LastFm;
import com.tivo.hme.sdk.util.Mp3Helper;
/**
* This class represents and manages playback of MP3 files.
*/
public class MP3File extends HMusic implements PlayableLocalTrack {
private String albumArtistName = "";
private String albumName = "";
private String artistName = "";
private String trackName = "";
private File trackFile;
private String trackPath = "";
private String trackNameTitleSortForm = "";
private int trackNumber;
private int releaseYear;
private int discNumber;
private RatingLevel rating = RatingLevel.UNRATED;
private long duration = -1;
private Boolean albumImageFetched = false;
private Boolean hasAlbumArt = false;
/**
* Constructor scans MP3 file for ID3 tags to get track information.
*
* @param path a String that represents the path to the track relative to the music root.
* @param file a <code>File</code> that represents the track on disk.
*/
public MP3File(String path, File file) throws ID3Exception {
this.trackFile = file;
this.trackPath = path;
// Create an org.blinkenlights.jid3.MP3File to read tag data from
org.blinkenlights.jid3.MP3File mp3File = new org.blinkenlights.jid3.MP3File(file);
// Get any ID3v2.3 tag that exists in the mp3 file and load its data
ID3V2_3_0Tag v23Tag = (ID3V2_3_0Tag) mp3File.getID3V2Tag();
if(v23Tag != null) {
// An ID3v2.3 tag exists, so pull text fields from tags
if( (v23Tag.getTALBTextInformationFrame() != null) && (v23Tag.getTALBTextInformationFrame().getAlbum() != null ) ){
this.albumName = removeDiscLabel(v23Tag.getTALBTextInformationFrame().getAlbum().trim());
}
if( (v23Tag.getTIT2TextInformationFrame() != null) && (v23Tag.getTIT2TextInformationFrame().getTitle() != null ) ) {
this.trackName = v23Tag.getTIT2TextInformationFrame().getTitle().trim();
}
if( v23Tag.getTRCKTextInformationFrame() != null ) {
this.trackNumber = v23Tag.getTRCKTextInformationFrame().getTrackNumber();
}
if( (v23Tag.getTPOSTextInformationFrame() != null) ) {
// Do not set the tag if there is only 1 totalPart
if(v23Tag.getTPOSTextInformationFrame().getTotalParts() != 1) {
this.discNumber = v23Tag.getTPOSTextInformationFrame().getPartNumber();
}
}
if(v23Tag.getTYERTextInformationFrame() != null) {
this.releaseYear = v23Tag.getTYERTextInformationFrame().getYear();
}
// Create title formatted string for track.
if(! this.trackName.equals("")) {
Matcher stringMatcher = titlePattern.matcher(this.trackName);
if(stringMatcher.lookingAt()) {
// Found a leading article. Move it to the end of the string.
this.trackNameTitleSortForm = stringMatcher.replaceFirst("") + ", " + stringMatcher.group(1);
}
else {
this.trackNameTitleSortForm = this.trackName;
}
}
// Artists are returned as an array of artists. Concatenate them into one string, if the frame exists.
if(v23Tag.getTPE1TextInformationFrame() != null) {
String[] tempArtistNameArray = v23Tag.getTPE1TextInformationFrame().getLeadPerformers();
if(tempArtistNameArray.length > 0) {
StringBuilder tempArtistNameBuilder = new StringBuilder(tempArtistNameArray[0].trim());
for(int i = 1; i < tempArtistNameArray.length; ++i) {
tempArtistNameBuilder.append('/').append(tempArtistNameArray[i].trim());
}
this.artistName = tempArtistNameBuilder.toString();
}
}
// AlbumArtist is a non-standard ID3 tag, and TPE2 isn't really intended for it. So if AlbumArtist is
// blank, copy the track artist into the album artist.
if( (v23Tag.getTPE2TextInformationFrame() != null) && ( ! v23Tag.getTPE2TextInformationFrame().getBandOrchestraAccompaniment().trim().equals("") ) ) {
this.albumArtistName = v23Tag.getTPE2TextInformationFrame().getBandOrchestraAccompaniment().trim();
}
if(this.albumArtistName.equals("")) {
this.albumArtistName = this.artistName;
}
/*
// Get any popularimeter (POPM) frames in the tag
POPMID3V2Frame[] POPMFrames = v23Tag.getPOPMFrames();
// Iterate through the POPM frams to see if any of them belong to us.
for(POPMID3V2Frame frame : POPMFrames) {
// Get email address of user
// TODO DEFERRED: implement for ratings: get email address from Preferences object
String myEmail = "harmonium@DazeEnd.org";
// Check if the frame belongs to us.
if( myEmail.equals( frame.getEmailToUser() ) ) {
// This is our tag, so get the rating and save it
switch(frame.getPopularity()) {
case 1:
this.rating = RatingLevel.LEVEL_1;
break;
case 2:
this.rating = RatingLevel.LEVEL_2;
break;
case 3:
this.rating = RatingLevel.LEVEL_3;
break;
case 4:
this.rating = RatingLevel.LEVEL_4;
break;
case 5:
this.rating = RatingLevel.LEVEL_5;
break;
default:
this.rating = RatingLevel.UNRATED;
}
// We've already found our rating, so stop looking by dropping out of the for-loop
break;
}
}
*/
}
// We've grabbed all the ID3v2.3 data. Now fill in any blanks with data from ID3v1.x tags.
// Note that ID3v1.x tags are much more limited than v2.3, so we won't be able to get all the data.
ID3V1Tag v1Tag = mp3File.getID3V1Tag();
if( (this.artistName.equals("")) && (v1Tag != null) && (v1Tag.getArtist() != null ) ) {
this.artistName = v1Tag.getArtist().trim();
}
if(this.albumArtistName.equals("")) {
// There's no way to get album artist from v1.x, so fake it.
this.albumArtistName = this.artistName;
}
if( (this.albumName.equals("")) && (v1Tag != null) && (v1Tag.getAlbum() != null ) ) {
this.albumName = removeDiscLabel(v1Tag.getAlbum().trim());
}
if( (this.trackName.equals("")) && (v1Tag != null) && (v1Tag.getTitle() != null ) ) {
this.trackName = v1Tag.getTitle();
}
if(this.releaseYear == 0 && (v1Tag != null)) {
try{
this.releaseYear = Integer.parseInt(v1Tag.getYear());
}
catch(NumberFormatException e) {
// If we get a bad number from the tag, just skip it.
}
}
if((this.trackNumber == 0) && (v1Tag != null) && (v1Tag instanceof ID3V1_1Tag)) {
try {
this.trackNumber = ((ID3V1_1Tag) v1Tag).getAlbumTrack();
}
catch(ClassCastException e) {
// If there's a problem with the cast, just skip this field.
}
}
// Find the length of this track in milliseconds
try {
InputStream in = new FileInputStream(file);
try {
Mp3Helper mp3Helper = new Mp3Helper(in, file.length());
this.duration = mp3Helper.getMp3Duration();
} finally {
try {
in.close();
}
catch(IOException e) {
}
}
}
catch(FileNotFoundException e) {
}
}
private static final Pattern discPattern = Pattern.compile("(?i)(.*)(\\s+[\\(\\[\\{]?Disc\\s[0-9]+[\\)\\]\\}]?)\\z");
private static final Pattern cdPattern = Pattern.compile("(?i)(.*)(\\s+[\\(\\[\\{]?CD\\s[0-9]+[\\)\\]\\}]?)\\z");
private static String removeDiscLabel(String originalName)
{
Matcher m = discPattern.matcher(originalName);
if (m.lookingAt())
return m.group(1);
else {
m = cdPattern.matcher(originalName);
if (m.lookingAt())
return m.group(1);
else
return originalName;
}
}
/**
* Constructor takes track information as parameters and does not scan file for ID3 tags.
*
* @param path a String that represents the path to the track relative to the music root.
* @param file a <code>File</code> that represents the track on disk.
*/
public MP3File( String path, // path to file relative to music root
File file, // file object representing track on disk
String albumArtist,
String albumName,
int yearNum, // Release year
int discNum, // disc number for multi-part albums. (Use zero for no disc number.)
int trackNum,
String trackName,
String artistName,
long duration
) {
this.trackFile = file;
this.trackPath = path;
this.albumArtistName = albumArtist;
this.albumName = albumName;
this.releaseYear = yearNum;
this.discNumber = discNum;
this.trackNumber = trackNum;
this.trackName = trackName;
this.artistName = artistName;
this.duration = duration;
// Create title formatted string for track.
if(! this.trackName.equals("")) {
// The track has a name, so re-format it
// Compile pattern for matching leading articles
Matcher stringMatcher = titlePattern.matcher(this.trackName);
if(stringMatcher.lookingAt()) {
// Found a leading article. Move it to the end of the string.
this.trackNameTitleSortForm = stringMatcher.replaceFirst("") + ", " + stringMatcher.group(1);
}
else {
this.trackNameTitleSortForm = this.trackName;
}
}
}
/* (non-Javadoc)
* @see org.dazeend.harmonium.music.Playable#getDuration()
*/
public long getDuration() {
return this.duration;
}
/**
* Checks existence of album art for this object.
*/
//@Override
public boolean hasAlbumArt(FactoryPreferences prefs) {
if ( albumImageFetched )
return hasAlbumArt;
return (this.getAlbumArt(prefs) != null);
}
private Image getAlbumArtFromID3Tag(FactoryPreferences prefs)
{
if (prefs.inDebugMode())
System.out.println("Retrieving embedded cover art from " + this.trackFile.getAbsolutePath());
Image img = null;
// Create an org.blinkenlights.jid3.MP3File to read tag data from
org.blinkenlights.jid3.MP3File mp3File = new org.blinkenlights.jid3.MP3File(this.trackFile);
// Get any ID3v2.3 tag that exists in the mp3 file and load its data
ID3V2_3_0Tag v23Tag;
try {
v23Tag = (ID3V2_3_0Tag) mp3File.getID3V2Tag();
}
catch(ID3Exception e) {
// There was an error reading the ID3 info, so just return null
return null;
}
if(v23Tag != null) {
// Get any attached picture (APIC) frames in this tag.
APICID3V2Frame[] APICFrames = v23Tag.getAPICFrames();
if(APICFrames.length > 0) {
// APIC frames categorize each attached picture with a "picture type". If a picture with the type
// of "front cover" exists, use that picture -- it should be the album art. If there's no picture
// with a type of "front cover" just use the first picture in the array.
for(APICID3V2Frame frame : APICFrames) {
if( frame.getPictureType().equals(APICID3V2Frame.PictureType.FrontCover) ) {
// Make sure that the MIME type for this cover art can be understood by TiVo
String tempMimeType = frame.getMimeType();
for(TivoImageFormat format : TivoImageFormat.values()) {
if(format.getMimeType().equals(tempMimeType)) {
img = new ImageIcon(frame.getPictureData()).getImage();
break;
}
}
// We found the cover art, so stop looking for it.
break;
}
}
// If we didn't find an attached picture that claims to be of the front cover, just grab
// the first valid image.
if(img == null) {
for(APICID3V2Frame frame : APICFrames) {
// Make sure that the MIME type for this album art can be understood by TiVo
String tempMimeType = frame.getMimeType();
for(TivoImageFormat format : TivoImageFormat.values()) {
if(format.getMimeType().equals(tempMimeType)) {
img = new ImageIcon(frame.getPictureData()).getImage();
if (img.getWidth(null) < 1 || img.getHeight(null) < 1)
img = null;
else
break;
}
}
if (img != null)
break;
}
}
}
}
return img;
}
private Image getAlbumArtFromFile(FactoryPreferences prefs) throws IOException
{
if (prefs.inDebugMode())
System.out.println("Retrieving file-based cover art for " + this.trackFile.getAbsolutePath());
Image img = null;
File parentFolder = this.trackFile.getParentFile();
String possibleImageFileName = null;
String imageFileName = null;
String[] files = parentFolder.list();
if (files != null)
{
for (int i = 0; i < files.length; i++)
{
if (files[i].equalsIgnoreCase("folder.jpg") || files[i].equalsIgnoreCase("cover.jpg"))
{
imageFileName = files[i];
break;
}
else if (possibleImageFileName == null)
{
String extension = files[i].substring(files[i].length() - 4);
if (extension.equalsIgnoreCase(".jpg"))
possibleImageFileName = files[i];
}
}
}
if (imageFileName == null && possibleImageFileName != null)
imageFileName = possibleImageFileName;
if (imageFileName != null)
{
String imageFilePath = parentFolder.getCanonicalPath() + File.separatorChar + imageFileName;
img = new ImageIcon(imageFilePath).getImage();
}
return img;
}
/*
private BufferedReader read(String url) throws Exception{
return new BufferedReader(
new InputStreamReader(
new URL(url).openStream()));}
*/
//This function connects to last.fm, retrieves a URL to album art and downloads the album art
private Image getAlbumArtFromHTTP(FactoryPreferences prefs) throws Exception
{
Image img = LastFm.fetchAlbumArt(artistName, albumName);
if (img == null && prefs.inDebugMode())
{
System.out.println("No Album Art Found by http For Artist: " + artistName + " Album: " + albumName);
}
if(img != null)
{
if (prefs.inDebugMode())
System.out.println("Found album cover by http for " + artistName + "-" + albumName);
saveAlbumArtToCache(img,prefs);
/*
org.blinkenlights.jid3.MP3File mp3File = new org.blinkenlights.jid3.MP3File(this.trackFile);
// Get any ID3v2.3 tag that exists in the mp3 file and load its data
ID3V2_3_0Tag v23Tag;
try {
v23Tag = (ID3V2_3_0Tag) mp3File.getID3V2Tag();
}
catch(ID3Exception e) {
//Dont update the ID3 tag and move on, the image is still good for the cache.
System.out.println("Album Art Found But Exception when getting ID3V2 tag for " + this.trackFile.getAbsolutePath());
return img;
}
if(v23Tag != null)
{
//Get the byte representation of the image
ImageAttributes ImageMeasurer = new ImageAttributes(img);
byte[] pictureData = ImageMeasurer.getImageBytes();
//Create a new ID3 frame and load it with the picture data
APICID3V2Frame newFrontCover = new APICID3V2Frame("image/jpeg",APICID3V2Frame.PictureType.FrontCover,"Album Cover Retrieved by Harmonium",pictureData);
v23Tag.addAPICFrame(newFrontCover);
//Update the ID3 information stored in memory
mp3File.setID3Tag(v23Tag);
//Write the ID3 information to the Hard Disk
mp3File.sync();
if(prefs.inDebugMode())
{
System.out.println("Wrote cover art to " + this.trackFile.getAbsolutePath());
}
}
else if(prefs.inDebugMode())
System.out.println("Album Art Found But No ID3V2 tag for " + this.trackFile.getAbsolutePath());
*/
}
return img;
}
/* (non-Javadoc)
* @see org.dazeend.harmonium.Playable#getAlbumArt()
*/
//@Override
public synchronized Image getAlbumArt(FactoryPreferences prefs) {
Image img = null;
try
{
// If set to prefer file-based art, and not ignoring file-based art, look for that first.
if (prefs.preferJpgFileArt() &&!prefs.ignoreJpgFileArt())
img = getAlbumArtFromFile(prefs);
// If we don't yet have an image and we're not ignoring embedded art, look there.
if (img == null && !prefs.ignoreEmbeddedArt())
img = getAlbumArtFromID3Tag(prefs);
// If we still don't have an image, and we didn't already look at file-based art,
// and we're not ignoring file-based art, look for it now.
if (img == null && !prefs.preferJpgFileArt() && !prefs.ignoreJpgFileArt())
img = getAlbumArtFromFile(prefs);
//See if we have cached downloaded art
if (img == null)
img = retrieveAlbumArtFromCache(prefs);
//If we still dont have it, give the online service a shot.
if (img == null && prefs.includeHTTP())
img = getAlbumArtFromHTTP(prefs);
hasAlbumArt = (img != null);
}
catch (Throwable t)
{
hasAlbumArt = false;
t.printStackTrace();
}
finally
{
albumImageFetched = true;
}
return img;
}
public void saveAlbumArtToCache(Image coverArt, FactoryPreferences prefs) {
//see if album exists, if it does return its artsource
//Album.artSource.getAlbumArt()
String albumArtCacheFolder = MusicCollection.getMusicCollection(null).getAlbumArtCacheFolderPath();
String fileNameTemp = artistName.trim()+"-"+albumName.trim();
fileNameTemp = fileNameTemp.replaceAll("[\\/:\"*?<>|]+","");
String fileName = albumArtCacheFolder+File.separator+fileNameTemp;
File targetFileName = new File(fileName + ".jpg");
//did we already fetch this albums art?
if (targetFileName.exists())
return;
//Perhaps the cache doesnt exist yet? Create it then!
File targetDir = new File(albumArtCacheFolder);
if (!targetDir.exists())
targetDir.mkdirs();
if(prefs.inDebugMode())
System.out.println("Album Art Saved To " + fileName + ".jpg");
ImageAttributes ImageMeasurer = new ImageAttributes(coverArt);
ImageMeasurer.saveToFile(fileName);
}
public Image retrieveAlbumArtFromCache(FactoryPreferences prefs) {
if (prefs.inDebugMode())
System.out.println("Retrieving cache-based cover art for " + this.trackFile.getAbsolutePath());
String albumArtCacheFolder = MusicCollection.getMusicCollection(null).getAlbumArtCacheFolderPath();
//Strip illegal charachters from the artist and album name
String fileNameTemp = artistName.trim()+"-"+albumName.trim();
fileNameTemp = fileNameTemp.replaceAll("[\\/:\"*?<>|]+","");
String fileName = albumArtCacheFolder+File.separator+fileNameTemp;
try {
File targetFileName = new File(fileName + ".jpg");
//did we already fetch this albums art?
if (targetFileName.exists()){
Image returnImage = ImageIO.read(targetFileName);
return returnImage;
}
}
catch (IOException e) {
e.printStackTrace();
}
return null;
}
/* (non-Javadoc)
* @see org.dazeend.harmonium.Playable#getAlbumArtistName()
*/
//@Override
public String getAlbumArtistName() {
return this.albumArtistName;
}
/* (non-Javadoc)
* @see org.dazeend.harmonium.Playable#getAlbumName()
*/
//@Override
public String getAlbumName() {
return this.albumName;
}
/* (non-Javadoc)
* @see org.dazeend.harmonium.Playable#getArtistName()
*/
//@Override
public String getArtistName() {
return this.artistName;
}
/* (non-Javadoc)
* @see org.dazeend.harmonium.Playable#getDiscNumber()
*/
//@Override
public int getDiscNumber() {
return this.discNumber;
}
/* (non-Javadoc)
* @see org.dazeend.harmonium.Playable#getRating()
*/
//@Override
public RatingLevel getRating() {
return this.rating;
}
/* (non-Javadoc)
* @see org.dazeend.harmonium.Playable#getReleaseYear()
*/
//@Override
public int getReleaseYear() {
return this.releaseYear;
}
/* (non-Javadoc
*
* Gets an Image containing scaled album art for this track.
*
*/
//@Override
public Image getScaledAlbumArt(FactoryPreferences prefs, int width, int height)
{
Image img = this.getAlbumArt(prefs);
if (img != null)
{
ImageIcon icon = new ImageIcon(img);
int imgW = icon.getIconWidth();
int imgH = icon.getIconHeight();
// figure out the scale factor and the new size
float scale = Math.min((float) width / imgW, (float) height / imgH);
if (scale > 1.0f) {
scale = 1.0f;
}
int scaleW = (int)(imgW * scale);
int scaleH = (int)(imgH * scale);
// Perform scaling if the image must be shrunk. We will send smaller
// images over and let the receiver scale them up.
if (scale < 1.0f) {
img = img.getScaledInstance(scaleW, scaleH, Image.SCALE_FAST);
// try {
// // the media tracker reqires a component, so we use this button
// Button mediaTrackerComp = new Button();
//
// // use MediaTracker to wait for image to be completely scaled. (I think? TiVo code.)
// MediaTracker mt = new MediaTracker(mediaTrackerComp);
// mt.addImage(img, 0);
// mt.waitForAll();
// } catch(InterruptedException e) {
// }
}
}
return img;
}
/**
* Gets the path to the track on disk relative to the music root.
*
* @return the path to the track on disk
*/
//@Override
public String getURI() {
return this.trackPath;
}
/**
* @return the filename
*/
//@Override
public String getFilename() {
return this.trackFile.getName();
}
/* (non-Javadoc)
* @see org.dazeend.harmonium.Playable#getTrackName()
*/
//@Override
public String getTrackName() {
return this.trackName;
}
/* (non-Javadoc)
* @see org.dazeend.harmonium.Playable#getTrackNameTitleSortForm()
*/
//@Override
public String getTrackNameTitleSortForm() {
return this.trackNameTitleSortForm;
}
/* (non-Javadoc)
* @see org.dazeend.harmonium.Playable#getTrackNumber()
*/
//@Override
public int getTrackNumber() {
return this.trackNumber;
}
/* (non-Javadoc)
* @see org.dazeend.harmonium.Playable#increaseRating()
*/
//@Override
public synchronized void increaseRating() {
// TODO DEFERRED: implement for ratings
}
/* (non-Javadoc)
* @see org.dazeend.harmonium.Playable#decreaseRating()
*/
//@Override
public synchronized void decreaseRating() {
// TODO DEFERRED: implement for ratings
}
/* (non-Javadoc)
* @see org.dazeend.harmonium.PlaylistEligible#listMemberTracks()
*/
//@Override
public List<Playable> getMembers(Harmonium app) {
// Playable objects are the leaf of the tree and there can be no other
// tracks below it. So return a list with only this object in it.
List<Playable> list = new ArrayList<Playable>();
list.add(this);
return list;
}
/* (non-Javadoc)
* @see org.dazeend.harmonium.Playable#toTitle()
*/
//@Override
public String toStringTitleSortForm() {
if((! this.trackNameTitleSortForm.equals("")) && (this.trackNameTitleSortForm != null)) {
return this.trackNameTitleSortForm;
}
else {
// The track doesn't have a name, so just return the track's filename
return this.trackFile.getName();
}
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
* @see org.dazeend.harmonium.Playable#toString()
*/
@Override
public String toString() {
// Prints track name, or failing that the filename.
if((! trackName.equals("")) && (this.trackName != null)) {
return this.trackName;
}
else {
// The track doesn't have a name, so just return the track's filename
return this.trackFile.getName();
}
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((trackFile == null) ? 0 : trackFile.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final MP3File other = (MP3File) obj;
if (trackFile == null) {
if (other.trackFile != null)
return false;
} else if (!trackFile.equals(other.trackFile))
return false;
return true;
}
/* (non-Javadoc)
* @see org.dazeend.harmonium.music.Playable#getTrackFile()
*/
public File getTrackFile() {
return this.trackFile;
}
public String getDisplayArtistName()
{
return getArtistName();
}
public String getArtHashKey()
{
return getAlbumArtistName() + getAlbumName() + getReleaseYear();
}
public String getContentType()
{
return "audio/mpeg";
}
//I defined this class here because I only need it for this very specific purpose.
//If we decide to expand on this for other things then we could throw this into its own file.
public class ImageAttributes extends Applet {
private static final long serialVersionUID = 1L;
public MediaTracker tr;
public Image intImg;
public ImageAttributes(Image img){
//We have to do this to ensure the image has loaded, otherwise when we
//attempt to create the BufferedImage our width and height will be -1
intImg = img;
tr = new MediaTracker(this);
tr.addImage(intImg, 0);
try {
tr.waitForAll();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
public byte[] getImageBytes(){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ImageIO.write(getBufferedImage(intImg), "JPEG", baos);
baos.flush();
byte[] resultImage = baos.toByteArray();
baos.close();
return resultImage;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public void saveToFile(String fileName){
BufferedImage buffImage = getBufferedImage(intImg);
save(buffImage, fileName, "jpg");
}
private void save(BufferedImage image, String fileName, String ext) {
File file = new File(fileName + "." + ext);
try {
ImageIO.write(image, ext, file); // ignore returned boolean
}
catch(IOException e) {
System.out.println("Write error for " + file.getPath() +
": " + e.getMessage());
}
}
private BufferedImage getBufferedImage(Image image) {
//ByteArrayOutputStream baos=new ByteArrayOutputStream(1000);
BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
bi.getGraphics().drawImage(image, 0,0,null);
return bi;
}
}
}
|