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;
|
package musicplayer.db;
|
||||||
|
|
||||||
|
import musicplayer.AlbumArtExtractor;
|
||||||
import musicplayer.model.*;
|
import musicplayer.model.*;
|
||||||
import org.hibernate.Criteria;
|
import org.hibernate.Criteria;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.criterion.Restrictions;
|
import org.hibernate.criterion.Restrictions;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -94,7 +96,7 @@ public class Gateway {
|
|||||||
session.beginTransaction();
|
session.beginTransaction();
|
||||||
Optional<Album> albumObj = getOneAlbum(metadata.album);
|
Optional<Album> albumObj = getOneAlbum(metadata.album);
|
||||||
if (!albumObj.isPresent()) {
|
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);
|
albumObj = Optional.of(album);
|
||||||
}
|
}
|
||||||
Optional<Artist> artistObj = getOneArtist(metadata.artist);
|
Optional<Artist> artistObj = getOneArtist(metadata.artist);
|
||||||
|
@ -24,11 +24,8 @@ public class ExtractedMetadata {
|
|||||||
public final String genre;
|
public final String genre;
|
||||||
public final String songFile;
|
public final String songFile;
|
||||||
public final String trackNumber;
|
public final String trackNumber;
|
||||||
public final byte[] artwork;
|
|
||||||
public final String discNumber;
|
public final String discNumber;
|
||||||
|
|
||||||
private static final String albumArtRegex = ".*(Cover|Folder|cover|folder)\\.(jpg|png)";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param audioTags jaudiotagger tag data.
|
* @param audioTags jaudiotagger tag data.
|
||||||
* @param songFile Location of the song file on the filesystem.
|
* @param songFile Location of the song file on the filesystem.
|
||||||
@ -41,51 +38,6 @@ public class ExtractedMetadata {
|
|||||||
this.genre = audioTags.getFirst(FieldKey.GENRE);
|
this.genre = audioTags.getFirst(FieldKey.GENRE);
|
||||||
this.discNumber = audioTags.getFirst(FieldKey.DISC_NO);
|
this.discNumber = audioTags.getFirst(FieldKey.DISC_NO);
|
||||||
this.songFile = songFile.getAbsolutePath();
|
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
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user