Refactored album art retrieval to prevent repeat loading of the same image into memory.
This commit is contained in:
parent
0401c626e2
commit
eb02ca7665
84
src/main/java/musicplayer/AlbumArtExtractor.java
Normal file
84
src/main/java/musicplayer/AlbumArtExtractor.java
Normal file
@ -0,0 +1,84 @@
|
||||
package musicplayer;
|
||||
|
||||
import org.jaudiotagger.audio.AudioFileIO;
|
||||
import org.jaudiotagger.audio.exceptions.CannotReadException;
|
||||
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
|
||||
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
|
||||
import org.jaudiotagger.tag.Tag;
|
||||
import org.jaudiotagger.tag.TagException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class AlbumArtExtractor {
|
||||
|
||||
private static final String albumArtRegex = ".*(Cover|Folder|cover|folder)\\.(jpg|png)";
|
||||
|
||||
/**
|
||||
* Get the album art for a song file.
|
||||
* @param songFile File from which to get album art data
|
||||
* (Data is either extracted from file metadata or an image in the same folder).
|
||||
* @return Album art as a byte array.
|
||||
*/
|
||||
public static byte[] getImageData(File songFile){
|
||||
Tag audioTags = null;
|
||||
try {
|
||||
audioTags = AudioFileIO.read(songFile).getTag();
|
||||
} catch (CannotReadException | IOException | ReadOnlyFileException | TagException | InvalidAudioFrameException e) {
|
||||
return null;
|
||||
}
|
||||
byte[] tmpArt = null;
|
||||
try {
|
||||
tmpArt = audioTags.getFirstArtwork().getBinaryData();
|
||||
BufferedImage image = ImageIO.read(new ByteArrayInputStream(tmpArt));
|
||||
tmpArt = convertImageToBytes(image);
|
||||
} catch (IOException | NullPointerException e) {
|
||||
try {
|
||||
Path dir = songFile.toPath().getParent();
|
||||
Optional<Path> imageFile = Files.walk(dir).filter(x -> x.toString().matches(albumArtRegex)).findFirst();
|
||||
if (imageFile.isPresent()) {
|
||||
Image actualImage = ImageIO.read(imageFile.get().toFile());
|
||||
tmpArt = convertImageToBytes(actualImage);
|
||||
}
|
||||
} catch (NullPointerException | IOException ignored) {}
|
||||
}
|
||||
return tmpArt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an Image into its' byte array representation.
|
||||
* @param image Image to convert.
|
||||
* @return image as byte[].
|
||||
*/
|
||||
private static byte[] convertImageToBytes(Image image){
|
||||
int imageScaleToSize = 50;
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()){
|
||||
ImageIO.write(convertToBufferedImage(image.getScaledInstance(imageScaleToSize, imageScaleToSize, Image.SCALE_SMOOTH)), "jpg", baos);
|
||||
baos.flush();
|
||||
return baos.toByteArray();
|
||||
} catch (IOException e) { return null; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an Image to a BufferedImage.
|
||||
* @param image Source image.
|
||||
* @return image as BufferedImage.
|
||||
*/
|
||||
private static BufferedImage convertToBufferedImage(Image image) {
|
||||
BufferedImage newImage = new BufferedImage(
|
||||
image.getWidth(null), image.getHeight(null),
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = newImage.createGraphics();
|
||||
g.drawImage(image, 0, 0, null);
|
||||
g.dispose();
|
||||
return newImage;
|
||||
}
|
||||
}
|
@ -1,10 +1,12 @@
|
||||
package musicplayer.db;
|
||||
|
||||
import musicplayer.AlbumArtExtractor;
|
||||
import musicplayer.model.*;
|
||||
import org.hibernate.Criteria;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@ -94,7 +96,7 @@ public class Gateway {
|
||||
session.beginTransaction();
|
||||
Optional<Album> albumObj = getOneAlbum(metadata.album);
|
||||
if (!albumObj.isPresent()) {
|
||||
Album album = new Album(metadata.album, metadata.artwork);
|
||||
Album album = new Album(metadata.album, AlbumArtExtractor.getImageData(new File(metadata.songFile)));
|
||||
albumObj = Optional.of(album);
|
||||
}
|
||||
Optional<Artist> artistObj = getOneArtist(metadata.artist);
|
||||
|
@ -24,11 +24,8 @@ public class ExtractedMetadata {
|
||||
public final String genre;
|
||||
public final String songFile;
|
||||
public final String trackNumber;
|
||||
public final byte[] artwork;
|
||||
public final String discNumber;
|
||||
|
||||
private static final String albumArtRegex = ".*(Cover|Folder|cover|folder)\\.(jpg|png)";
|
||||
|
||||
/**
|
||||
* @param audioTags jaudiotagger tag data.
|
||||
* @param songFile Location of the song file on the filesystem.
|
||||
@ -41,51 +38,6 @@ public class ExtractedMetadata {
|
||||
this.genre = audioTags.getFirst(FieldKey.GENRE);
|
||||
this.discNumber = audioTags.getFirst(FieldKey.DISC_NO);
|
||||
this.songFile = songFile.getAbsolutePath();
|
||||
byte[] tmpArt = null;
|
||||
try {
|
||||
tmpArt = audioTags.getFirstArtwork().getBinaryData();
|
||||
BufferedImage image = ImageIO.read(new ByteArrayInputStream(tmpArt));
|
||||
tmpArt = convertImageToBytes(image);
|
||||
} catch (IOException | NullPointerException e) {
|
||||
try {
|
||||
Path dir = songFile.toPath().getParent();
|
||||
Optional<Path> imageFile = Files.walk(dir).filter(x -> x.toString().matches(albumArtRegex)).findFirst();
|
||||
if (imageFile.isPresent()) {
|
||||
Image actualImage = ImageIO.read(imageFile.get().toFile());
|
||||
tmpArt = convertImageToBytes(actualImage);
|
||||
}
|
||||
} catch (NullPointerException | IOException ignored) {}
|
||||
}
|
||||
artwork = tmpArt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an Image into its' byte array representation.
|
||||
* @param image Image to convert.
|
||||
* @return image as byte[].
|
||||
*/
|
||||
private static byte[] convertImageToBytes(Image image){
|
||||
int imageScaleToSize = 50;
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()){
|
||||
ImageIO.write(convertToBufferedImage(image.getScaledInstance(imageScaleToSize, imageScaleToSize, Image.SCALE_SMOOTH)), "jpg", baos);
|
||||
baos.flush();
|
||||
return baos.toByteArray();
|
||||
} catch (IOException e) { return null; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an Image to a BufferedImage.
|
||||
* @param image Source image.
|
||||
* @return image as BufferedImage.
|
||||
*/
|
||||
private static BufferedImage convertToBufferedImage(Image image) {
|
||||
BufferedImage newImage = new BufferedImage(
|
||||
image.getWidth(null), image.getHeight(null),
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = newImage.createGraphics();
|
||||
g.drawImage(image, 0, 0, null);
|
||||
g.dispose();
|
||||
return newImage;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user