mirror of
https://github.com/mitb-archive/filebot
synced 2024-08-13 17:03:45 -04:00
Experiment with @2x artwork thumbnail support
This commit is contained in:
parent
fadebfae61
commit
79ee700001
@ -85,7 +85,7 @@ public final class ResourceManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Image getMultiResolutionImageIcon(BufferedImage baseImage, double baseScale) {
|
public static Image getMultiResolutionImage(BufferedImage baseImage, double baseScale) {
|
||||||
if (PRIMARY_SCALE_FACTOR == 1 && baseScale == 1) {
|
if (PRIMARY_SCALE_FACTOR == 1 && baseScale == 1) {
|
||||||
return baseImage;
|
return baseImage;
|
||||||
}
|
}
|
||||||
@ -108,7 +108,7 @@ public final class ResourceManager {
|
|||||||
return new BaseMultiResolutionImage(image.toArray(Image[]::new));
|
return new BaseMultiResolutionImage(image.toArray(Image[]::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final double PRIMARY_SCALE_FACTOR = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().getDefaultTransform().getScaleX();
|
private static final double PRIMARY_SCALE_FACTOR = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().getDefaultTransform().getScaleX();
|
||||||
|
|
||||||
private static BufferedImage scale(double scale, BufferedImage image) {
|
private static BufferedImage scale(double scale, BufferedImage image) {
|
||||||
int w = (int) (scale * image.getWidth());
|
int w = (int) (scale * image.getWidth());
|
||||||
|
@ -40,7 +40,12 @@ public enum ThumbnailServices implements ThumbnailProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected String getThumbnailResource(int id, ResolutionVariant variant) {
|
protected String getThumbnailResource(int id, ResolutionVariant variant) {
|
||||||
return getResource(variant == ResolutionVariant.NORMAL ? id + ".png" : id + "@2x.png");
|
switch (variant) {
|
||||||
|
case NORMAL:
|
||||||
|
return getResource(id + ".png");
|
||||||
|
default:
|
||||||
|
return getResource(id + "@2x.png");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Cache getCache(ResolutionVariant variant) {
|
protected Cache getCache(ResolutionVariant variant) {
|
||||||
@ -102,9 +107,7 @@ public enum ThumbnailServices implements ThumbnailProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<SearchResult, Icon> getThumbnails(List<SearchResult> keys) throws Exception {
|
public Map<SearchResult, Icon> getThumbnails(List<SearchResult> keys, ResolutionVariant variant) throws Exception {
|
||||||
ResolutionVariant variant = PRIMARY_SCALE_FACTOR > 1 ? ResolutionVariant.RETINA : ResolutionVariant.NORMAL;
|
|
||||||
|
|
||||||
int[] ids = keys.stream().mapToInt(SearchResult::getId).toArray();
|
int[] ids = keys.stream().mapToInt(SearchResult::getId).toArray();
|
||||||
byte[][] thumbnails = getThumbnails(ids, variant);
|
byte[][] thumbnails = getThumbnails(ids, variant);
|
||||||
|
|
||||||
@ -126,18 +129,7 @@ public enum ThumbnailServices implements ThumbnailProvider {
|
|||||||
BufferedImage baseImage = ImageIO.read(new ByteArrayInputStream(bytes));
|
BufferedImage baseImage = ImageIO.read(new ByteArrayInputStream(bytes));
|
||||||
double baseScale = variant.scaleFactor;
|
double baseScale = variant.scaleFactor;
|
||||||
|
|
||||||
return new ImageIcon(getMultiResolutionImageIcon(baseImage, baseScale));
|
return new ImageIcon(getMultiResolutionImage(baseImage, baseScale));
|
||||||
}
|
|
||||||
|
|
||||||
public enum ResolutionVariant {
|
|
||||||
|
|
||||||
NORMAL(1), RETINA(2);
|
|
||||||
|
|
||||||
public final int scaleFactor;
|
|
||||||
|
|
||||||
private ResolutionVariant(int scaleFactor) {
|
|
||||||
this.scaleFactor = scaleFactor;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -193,8 +193,8 @@ public final class WebServices {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<SearchResult, Icon> getThumbnails(List<SearchResult> keys) throws Exception {
|
public Map<SearchResult, Icon> getThumbnails(List<SearchResult> keys, ResolutionVariant variant) throws Exception {
|
||||||
return ThumbnailServices.TheMovieDB.getThumbnails(keys);
|
return ThumbnailServices.TheMovieDB.getThumbnails(keys, variant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,8 +235,8 @@ public final class WebServices {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<SearchResult, Icon> getThumbnails(List<SearchResult> keys) throws Exception {
|
public Map<SearchResult, Icon> getThumbnails(List<SearchResult> keys, ResolutionVariant variant) throws Exception {
|
||||||
return ThumbnailServices.TheTVDB.getThumbnails(keys);
|
return ThumbnailServices.TheTVDB.getThumbnails(keys, variant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +51,7 @@ import net.filebot.web.EpisodeListProvider;
|
|||||||
import net.filebot.web.SearchResult;
|
import net.filebot.web.SearchResult;
|
||||||
import net.filebot.web.SortOrder;
|
import net.filebot.web.SortOrder;
|
||||||
import net.filebot.web.ThumbnailProvider;
|
import net.filebot.web.ThumbnailProvider;
|
||||||
|
import net.filebot.web.ThumbnailProvider.ResolutionVariant;
|
||||||
|
|
||||||
class EpisodeListMatcher implements AutoCompleteMatcher {
|
class EpisodeListMatcher implements AutoCompleteMatcher {
|
||||||
|
|
||||||
@ -234,7 +235,7 @@ class EpisodeListMatcher implements AutoCompleteMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// prepare thumbnail images
|
// prepare thumbnail images
|
||||||
Function<SearchResult, Icon> thumbnail = thumbnail(options);
|
Function<SearchResult, Icon> thumbnail = thumbnail(options, parent);
|
||||||
|
|
||||||
// show selection dialog on EDT
|
// show selection dialog on EDT
|
||||||
Callable<SearchResult> showSelectDialog = () -> {
|
Callable<SearchResult> showSelectDialog = () -> {
|
||||||
@ -291,10 +292,10 @@ class EpisodeListMatcher implements AutoCompleteMatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Function<SearchResult, Icon> thumbnail(List<SearchResult> options) {
|
protected Function<SearchResult, Icon> thumbnail(List<SearchResult> options, Component parent) {
|
||||||
if (provider instanceof ThumbnailProvider) {
|
if (provider instanceof ThumbnailProvider) {
|
||||||
try {
|
try {
|
||||||
Map<SearchResult, Icon> thumbnails = ((ThumbnailProvider) provider).getThumbnails(options);
|
Map<SearchResult, Icon> thumbnails = ((ThumbnailProvider) provider).getThumbnails(options, ResolutionVariant.fromScaleFactor(parent));
|
||||||
if (thumbnails.size() > 0) {
|
if (thumbnails.size() > 0) {
|
||||||
return key -> thumbnails.getOrDefault(key, BlankThumbnail.BLANK_POSTER);
|
return key -> thumbnails.getOrDefault(key, BlankThumbnail.BLANK_POSTER);
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ import net.filebot.web.MoviePart;
|
|||||||
import net.filebot.web.SearchResult;
|
import net.filebot.web.SearchResult;
|
||||||
import net.filebot.web.SortOrder;
|
import net.filebot.web.SortOrder;
|
||||||
import net.filebot.web.ThumbnailProvider;
|
import net.filebot.web.ThumbnailProvider;
|
||||||
|
import net.filebot.web.ThumbnailProvider.ResolutionVariant;
|
||||||
|
|
||||||
class MovieMatcher implements AutoCompleteMatcher {
|
class MovieMatcher implements AutoCompleteMatcher {
|
||||||
|
|
||||||
@ -342,7 +343,7 @@ class MovieMatcher implements AutoCompleteMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// prepare thumbnail images
|
// prepare thumbnail images
|
||||||
Function<Movie, Icon> thumbnail = thumbnail(options);
|
Function<Movie, Icon> thumbnail = thumbnail(options, parent);
|
||||||
|
|
||||||
// show selection dialog on EDT
|
// show selection dialog on EDT
|
||||||
Callable<Movie> showSelectDialog = () -> {
|
Callable<Movie> showSelectDialog = () -> {
|
||||||
@ -407,10 +408,10 @@ class MovieMatcher implements AutoCompleteMatcher {
|
|||||||
First, Skip;
|
First, Skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Function<Movie, Icon> thumbnail(List<Movie> options) {
|
protected Function<Movie, Icon> thumbnail(List<Movie> options, Component parent) {
|
||||||
if (service instanceof ThumbnailProvider) {
|
if (service instanceof ThumbnailProvider) {
|
||||||
try {
|
try {
|
||||||
Map<SearchResult, Icon> thumbnails = ((ThumbnailProvider) service).getThumbnails((List) options);
|
Map<SearchResult, Icon> thumbnails = ((ThumbnailProvider) service).getThumbnails((List) options, ResolutionVariant.fromScaleFactor(parent));
|
||||||
if (thumbnails.size() > 0) {
|
if (thumbnails.size() > 0) {
|
||||||
return key -> thumbnails.getOrDefault(key, BlankThumbnail.BLANK_POSTER);
|
return key -> thumbnails.getOrDefault(key, BlankThumbnail.BLANK_POSTER);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.filebot.web;
|
package net.filebot.web;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -7,6 +8,21 @@ import javax.swing.Icon;
|
|||||||
|
|
||||||
public interface ThumbnailProvider {
|
public interface ThumbnailProvider {
|
||||||
|
|
||||||
Map<SearchResult, Icon> getThumbnails(List<SearchResult> keys) throws Exception;
|
Map<SearchResult, Icon> getThumbnails(List<SearchResult> keys, ResolutionVariant variant) throws Exception;
|
||||||
|
|
||||||
|
enum ResolutionVariant {
|
||||||
|
|
||||||
|
NORMAL(1), RETINA(2);
|
||||||
|
|
||||||
|
public final int scaleFactor;
|
||||||
|
|
||||||
|
private ResolutionVariant(int scaleFactor) {
|
||||||
|
this.scaleFactor = scaleFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResolutionVariant fromScaleFactor(Component parent) {
|
||||||
|
return parent.getGraphicsConfiguration().getDefaultTransform().getScaleX() > 1 ? ResolutionVariant.RETINA : ResolutionVariant.NORMAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user