mirror of
https://github.com/magefree/mage.git
synced 2025-12-25 13:02:06 -08:00
[feature] Card images are now saved and read from zip files
This commit is contained in:
parent
e0d4285a69
commit
fa82f1b159
5 changed files with 111 additions and 106 deletions
|
|
@ -1,5 +1,10 @@
|
|||
package org.mage.plugins.card.images;
|
||||
|
||||
import de.schlichtherle.truezip.file.TArchiveDetector;
|
||||
import de.schlichtherle.truezip.file.TConfig;
|
||||
import de.schlichtherle.truezip.file.TFile;
|
||||
import de.schlichtherle.truezip.file.TFileOutputStream;
|
||||
import de.schlichtherle.truezip.fs.FsOutputOption;
|
||||
import mage.cards.Card;
|
||||
import mage.client.dialog.PreferencesDialog;
|
||||
import mage.remote.Connection;
|
||||
|
|
@ -61,6 +66,9 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
|
||||
public static void main(String[] args) {
|
||||
startDownload(null, null, null);
|
||||
TConfig config = TConfig.get();
|
||||
config.setArchiveDetector(new TArchiveDetector("zip"));
|
||||
config.getOutputPreferences().set(FsOutputOption.STORE);
|
||||
}
|
||||
|
||||
public static void startDownload(JFrame frame, Set<Card> allCards, String imagesPath) {
|
||||
|
|
@ -204,7 +212,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
}
|
||||
|
||||
public static boolean checkForNewCards(Set<Card> allCards, String imagesPath) {
|
||||
File file;
|
||||
TFile file;
|
||||
for (Card card : allCards) {
|
||||
if (card.getCardNumber() > 0 && !card.getExpansionSetCode().isEmpty()) {
|
||||
CardInfo url = new CardInfo(card.getName(), card.getExpansionSetCode(), card.getCardNumber(), 0, false, card.canTransform(), card.isNightCard());
|
||||
|
|
@ -212,9 +220,10 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
if (basicLandPattern.matcher(card.getName()).matches()) {
|
||||
withCollectorId = true;
|
||||
}
|
||||
file = new File(CardImageUtils.getImagePath(url, withCollectorId, imagesPath));
|
||||
if (!file.exists())
|
||||
file = new TFile(CardImageUtils.getImagePath(url, withCollectorId, imagesPath));
|
||||
if (!file.exists()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
@ -267,7 +276,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
log.error(e);
|
||||
}
|
||||
|
||||
File file;
|
||||
TFile file;
|
||||
|
||||
/**
|
||||
* check to see which cards we already have
|
||||
|
|
@ -277,7 +286,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
if (basicLandPattern.matcher(card.getName()).matches()) {
|
||||
withCollectorId = true;
|
||||
}
|
||||
file = new File(CardImageUtils.getImagePath(card, withCollectorId, imagesPath));
|
||||
file = new TFile(CardImageUtils.getImagePath(card, withCollectorId, imagesPath));
|
||||
if (!file.exists()) {
|
||||
cardsToDownload.add(card);
|
||||
}
|
||||
|
|
@ -300,16 +309,11 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
|
||||
private static ArrayList<CardInfo> getTokenCardUrls() throws RuntimeException {
|
||||
ArrayList<CardInfo> list = new ArrayList<CardInfo>();
|
||||
HashSet<String> filter = new HashSet<String>();
|
||||
InputStream in = DownloadPictures.class.getClassLoader().getResourceAsStream("card-pictures-tok.txt");
|
||||
readImageURLsFromFile(in, list, filter);
|
||||
return list;
|
||||
}
|
||||
|
||||
private static void readImageURLsFromFile(InputStream in, ArrayList<CardInfo> list, Set<String> filter) throws RuntimeException {
|
||||
if (in == null) {
|
||||
log.error("resources input stream is null");
|
||||
return;
|
||||
return list;
|
||||
}
|
||||
|
||||
BufferedReader reader = null;
|
||||
|
|
@ -361,6 +365,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
}
|
||||
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -414,7 +419,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
}
|
||||
|
||||
if (url != null) {
|
||||
Runnable task = new DownloadTask(card, new URL(url), imagesPath);
|
||||
Runnable task = new DownloadTask(card, new URL(url));
|
||||
executor.execute(task);
|
||||
} else {
|
||||
synchronized (sync) {
|
||||
|
|
@ -439,38 +444,34 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
|
||||
private CardInfo card;
|
||||
private URL url;
|
||||
private String imagesPath;
|
||||
|
||||
public DownloadTask(CardInfo card, URL url, String imagesPath) {
|
||||
public DownloadTask(CardInfo card, URL url) {
|
||||
this.card = card;
|
||||
this.url = url;
|
||||
this.imagesPath = imagesPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
createDirForCard(card, imagesPath);
|
||||
|
||||
boolean withCollectorId = false;
|
||||
if (basicLandPattern.matcher(card.getName()).matches()) {
|
||||
withCollectorId = true;
|
||||
}
|
||||
File fileOut = new File(CardImageUtils.getImagePath(card, withCollectorId));
|
||||
File temporaryFile = new File(Constants.IO.imageBaseDir + File.separator + card.hashCode() + "." + card.getName() + ".jpg");
|
||||
|
||||
BufferedInputStream in = new BufferedInputStream(url.openConnection(p).getInputStream());
|
||||
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fileOut));
|
||||
BufferedOutputStream out = new BufferedOutputStream(new TFileOutputStream(temporaryFile));
|
||||
|
||||
byte[] buf = new byte[1024];
|
||||
int len = 0;
|
||||
int len;
|
||||
while ((len = in.read(buf)) != -1) {
|
||||
// user cancelled
|
||||
if (cancel) {
|
||||
in.close();
|
||||
out.flush();
|
||||
out.close();
|
||||
// delete what was written so far
|
||||
fileOut.delete();
|
||||
temporaryFile.delete();
|
||||
return;
|
||||
}
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
|
|
@ -479,8 +480,10 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
out.flush();
|
||||
out.close();
|
||||
|
||||
TFile outputFile = new TFile(CardImageUtils.getImagePath(card, withCollectorId));
|
||||
if (card.isTwoFacedCard()) {
|
||||
BufferedImage image = ImageIO.read(fileOut);
|
||||
BufferedImage image = ImageIO.read(temporaryFile);
|
||||
temporaryFile.delete();
|
||||
if (image.getHeight() == 470) {
|
||||
BufferedImage renderedImage = new BufferedImage(265, 370, BufferedImage.TYPE_INT_RGB);
|
||||
renderedImage.getGraphics();
|
||||
|
|
@ -491,20 +494,23 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
graphics2D.drawImage(image, 0, 0, 265, 370, 41, 62, 306, 432, null);
|
||||
}
|
||||
graphics2D.dispose();
|
||||
writeImageToFile(renderedImage, fileOut);
|
||||
writeImageToFile(renderedImage, outputFile);
|
||||
}
|
||||
} else {
|
||||
new TFile(temporaryFile).cp_rp(outputFile);
|
||||
temporaryFile.delete();
|
||||
}
|
||||
|
||||
synchronized (sync) {
|
||||
update(cardIndex + 1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e, e);
|
||||
}
|
||||
|
||||
synchronized (sync) {
|
||||
update(cardIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeImageToFile(BufferedImage image, File file) throws IOException {
|
||||
private void writeImageToFile(BufferedImage image, TFile file) throws IOException {
|
||||
Iterator iter = ImageIO.getImageWritersByFormatName("jpg");
|
||||
|
||||
ImageWriter writer = (ImageWriter) iter.next();
|
||||
|
|
@ -512,21 +518,17 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
||||
iwp.setCompressionQuality(0.96f);
|
||||
|
||||
FileImageOutputStream output = new FileImageOutputStream(file);
|
||||
File tempFile = new File(Constants.IO.imageBaseDir + File.separator + image.hashCode() + file.getName());
|
||||
FileImageOutputStream output = new FileImageOutputStream(tempFile);
|
||||
writer.setOutput(output);
|
||||
IIOImage image2 = new IIOImage(image, null, null);
|
||||
writer.write(null, image2, iwp);
|
||||
writer.dispose();
|
||||
output.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static File createDirForCard(CardInfo card, String imagesPath) throws Exception {
|
||||
File setDir = new File(CardImageUtils.getImageDir(card, imagesPath));
|
||||
if (!setDir.exists()) {
|
||||
setDir.mkdirs();
|
||||
new TFile(tempFile).cp_rp(file);
|
||||
tempFile.delete();
|
||||
}
|
||||
return setDir;
|
||||
}
|
||||
|
||||
private void update(int card) {
|
||||
|
|
@ -545,7 +547,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
|
|||
if (basicLandPattern.matcher(cardInfo.getName()).matches()) {
|
||||
withCollectorId = true;
|
||||
}
|
||||
File file = new File(CardImageUtils.getImagePath(cardInfo, withCollectorId));
|
||||
TFile file = new TFile(CardImageUtils.getImagePath(cardInfo, withCollectorId));
|
||||
if (file.exists()) {
|
||||
cardsIterator.remove();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,19 +4,20 @@ import com.google.common.base.Function;
|
|||
import com.google.common.collect.ComputationException;
|
||||
import com.google.common.collect.MapMaker;
|
||||
import com.mortennobel.imagescaling.ResampleOp;
|
||||
import de.schlichtherle.truezip.file.TFile;
|
||||
import de.schlichtherle.truezip.file.TFileInputStream;
|
||||
import de.schlichtherle.truezip.file.TFileOutputStream;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.imageio.ImageIO;
|
||||
import mage.view.CardView;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.mage.plugins.card.constants.Constants;
|
||||
import org.mage.plugins.card.utils.CardImageUtils;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* This class stores ALL card images in a cache with soft values. this means
|
||||
* that the images may be garbage collected when they are not needed any more, but will
|
||||
|
|
@ -65,21 +66,27 @@ public class ImageCache {
|
|||
|
||||
CardInfo info = new CardInfo(name, set, collectorId, type);
|
||||
|
||||
if (collectorId == 0) info.setToken(true);
|
||||
if (collectorId == 0) {
|
||||
info.setToken(true);
|
||||
}
|
||||
String path = CardImageUtils.getImagePath(info);
|
||||
if (path == null) return null;
|
||||
File file = new File(path);
|
||||
if (path == null) {
|
||||
return null;
|
||||
}
|
||||
TFile file = new TFile(path);
|
||||
|
||||
if (thumbnail && path.endsWith(".jpg")) {
|
||||
String thumbnailPath = path.replace(".jpg", ".thumb.jpg");
|
||||
File thumbnailFile = new File(thumbnailPath);
|
||||
String thumbnailPath = path.replace(".zip", ".thumb.zip");
|
||||
TFile thumbnailFile = new TFile(thumbnailPath);
|
||||
if (thumbnailFile.exists()) {
|
||||
//log.debug("loading thumbnail for " + key + ", path="+thumbnailPath);
|
||||
return loadImage(thumbnailFile);
|
||||
} else {
|
||||
BufferedImage image = loadImage(file);
|
||||
image = getWizardsCard(image);
|
||||
if (image == null) return null;
|
||||
if (image == null) {
|
||||
return null;
|
||||
}
|
||||
//log.debug("creating thumbnail for " + key);
|
||||
return makeThumbnail(image, thumbnailPath);
|
||||
}
|
||||
|
|
@ -91,10 +98,11 @@ public class ImageCache {
|
|||
"Requested image doesn't fit the requirement for key (<cardname>#<setname>#<collectorID>): " + key);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
if (ex instanceof ComputationException)
|
||||
if (ex instanceof ComputationException) {
|
||||
throw (ComputationException) ex;
|
||||
else
|
||||
} else {
|
||||
throw new ComputationException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -138,8 +146,9 @@ public class ImageCache {
|
|||
// legitimate, happens when a card has no image
|
||||
return null;
|
||||
} catch (ComputationException ex) {
|
||||
if (ex.getCause() instanceof NullPointerException)
|
||||
if (ex.getCause() instanceof NullPointerException) {
|
||||
return null;
|
||||
}
|
||||
log.error(ex,ex);
|
||||
return null;
|
||||
}
|
||||
|
|
@ -163,13 +172,15 @@ public class ImageCache {
|
|||
* file to load image from
|
||||
* @return {@link BufferedImage}
|
||||
*/
|
||||
public static BufferedImage loadImage(File file) {
|
||||
public static BufferedImage loadImage(TFile file) {
|
||||
BufferedImage image = null;
|
||||
if (!file.exists()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
image = ImageIO.read(file);
|
||||
TFileInputStream inputStream = new TFileInputStream(file);
|
||||
image = ImageIO.read(inputStream);
|
||||
inputStream.close();
|
||||
} catch (Exception e) {
|
||||
log.error(e, e);
|
||||
}
|
||||
|
|
@ -179,10 +190,12 @@ public class ImageCache {
|
|||
|
||||
public static BufferedImage makeThumbnail(BufferedImage original, String path) {
|
||||
BufferedImage image = getResizedImage(original, Constants.THUMBNAIL_SIZE_FULL);
|
||||
File imagePath = new File(path);
|
||||
TFile imageFile = new TFile(path);
|
||||
try {
|
||||
//log.debug("thumbnail path:"+path);
|
||||
ImageIO.write(image, "jpg", imagePath);
|
||||
TFileOutputStream outputStream = new TFileOutputStream(imageFile);
|
||||
ImageIO.write(image, "jpg", outputStream);
|
||||
outputStream.close();
|
||||
} catch (Exception e) {
|
||||
log.error(e,e);
|
||||
}
|
||||
|
|
@ -203,8 +216,9 @@ public class ImageCache {
|
|||
int tgtWidth = Constants.CARD_SIZE_FULL.width;
|
||||
int tgtHeight = Constants.CARD_SIZE_FULL.height;
|
||||
|
||||
if (srcWidth == tgtWidth && srcHeight == tgtHeight)
|
||||
if (srcWidth == tgtWidth && srcHeight == tgtHeight) {
|
||||
return original;
|
||||
}
|
||||
|
||||
ResampleOp resampleOp = new ResampleOp(tgtWidth, tgtHeight);
|
||||
BufferedImage image = resampleOp.filter(original, null);
|
||||
|
|
@ -216,8 +230,9 @@ public class ImageCache {
|
|||
* panel For future use.
|
||||
*/
|
||||
private static BufferedImage getFullSizeImage(BufferedImage original, double scale) {
|
||||
if (scale == 1)
|
||||
if (scale == 1) {
|
||||
return original;
|
||||
}
|
||||
ResampleOp resampleOp = new ResampleOp((int) (original.getWidth() * scale), (int) (original.getHeight() * scale));
|
||||
BufferedImage image = resampleOp.filter(original, null);
|
||||
return image;
|
||||
|
|
@ -239,12 +254,14 @@ public class ImageCache {
|
|||
public static BufferedImage getImage(CardView card, int width, int height) {
|
||||
String key = getKey(card);
|
||||
BufferedImage original = getImage(key);
|
||||
if (original == null)
|
||||
if (original == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
double scale = Math.min((double) width / original.getWidth(), (double) height / original.getHeight());
|
||||
if (scale > 1)
|
||||
if (scale > 1) {
|
||||
scale = 1;
|
||||
}
|
||||
|
||||
return getFullSizeImage(original, scale);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
package org.mage.plugins.card.utils;
|
||||
|
||||
import de.schlichtherle.truezip.file.TFile;
|
||||
import java.util.HashMap;
|
||||
import org.mage.plugins.card.constants.Constants;
|
||||
import org.mage.plugins.card.images.CardInfo;
|
||||
import org.mage.plugins.card.properties.SettingsManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class CardImageUtils {
|
||||
|
||||
private static HashMap<CardInfo, String> pathCache = new HashMap<CardInfo, String>();
|
||||
|
|
@ -22,17 +21,17 @@ public class CardImageUtils {
|
|||
String filePath;
|
||||
String suffix = ".jpg";
|
||||
|
||||
File file = null;
|
||||
TFile file;
|
||||
if (card.isToken()) {
|
||||
if (pathCache.containsKey(card)) {
|
||||
return pathCache.get(card);
|
||||
}
|
||||
filePath = getTokenImagePath(card);
|
||||
file = new File(filePath);
|
||||
file = new TFile(filePath);
|
||||
|
||||
if (!file.exists()) {
|
||||
filePath = searchForCardImage(card);
|
||||
file = new File(filePath);
|
||||
file = new TFile(filePath);
|
||||
}
|
||||
|
||||
if (file.exists()) {
|
||||
|
|
@ -40,11 +39,11 @@ public class CardImageUtils {
|
|||
}
|
||||
} else {
|
||||
filePath = getImagePath(card, false);
|
||||
file = new File(filePath);
|
||||
file = new TFile(filePath);
|
||||
|
||||
if (!file.exists()) {
|
||||
filePath = getImagePath(card, true);
|
||||
file = new File(filePath);
|
||||
file = new TFile(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -53,7 +52,7 @@ public class CardImageUtils {
|
|||
*/
|
||||
if (file == null || !file.exists()) {
|
||||
filePath = cleanString(card.getName()) + suffix;
|
||||
file = new File(filePath);
|
||||
file = new TFile(filePath);
|
||||
}
|
||||
|
||||
if (file.exists()) {
|
||||
|
|
@ -66,17 +65,16 @@ public class CardImageUtils {
|
|||
private static String getTokenImagePath(CardInfo card) {
|
||||
String filename = getImagePath(card, false);
|
||||
|
||||
File file = new File(filename);
|
||||
TFile file = new TFile(filename);
|
||||
if (!file.exists()) {
|
||||
CardInfo updated = new CardInfo(card);
|
||||
updated.setName(card.getName() + " 1");
|
||||
filename = getImagePath(updated, false);
|
||||
file = new File(filename);
|
||||
file = new TFile(filename);
|
||||
if (!file.exists()) {
|
||||
updated = new CardInfo(card);
|
||||
updated.setName(card.getName() + " 2");
|
||||
filename = getImagePath(updated, false);
|
||||
file = new File(filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -84,14 +82,14 @@ public class CardImageUtils {
|
|||
}
|
||||
|
||||
private static String searchForCardImage(CardInfo card) {
|
||||
File file = null;
|
||||
String path = "";
|
||||
TFile file;
|
||||
String path;
|
||||
CardInfo c = new CardInfo(card);
|
||||
|
||||
for (String set : SettingsManager.getIntance().getTokenLookupOrder()) {
|
||||
c.setSet(set);
|
||||
path = getTokenImagePath(c);
|
||||
file = new File(path);
|
||||
file = new TFile(path);
|
||||
if (file.exists()) {
|
||||
pathCache.put(card, path);
|
||||
return path;
|
||||
|
|
@ -106,9 +104,9 @@ public class CardImageUtils {
|
|||
char c;
|
||||
for (int i = 0; i < in.length(); i++) {
|
||||
c = in.charAt(i);
|
||||
if (c == ' ' || c == '-')
|
||||
if (c == ' ' || c == '-') {
|
||||
out.append('_');
|
||||
else if (Character.isLetterOrDigit(c)) {
|
||||
} else if (Character.isLetterOrDigit(c)) {
|
||||
out.append(c);
|
||||
}
|
||||
}
|
||||
|
|
@ -134,9 +132,9 @@ public class CardImageUtils {
|
|||
String set = updateSet(card.getSet(), false).toUpperCase();
|
||||
String imagesDir = (imagesPath != null ? imagesPath : Constants.IO.imageBaseDir);
|
||||
if (card.isToken()) {
|
||||
return imagesDir + File.separator + "TOK" + File.separator + set;
|
||||
return imagesDir + TFile.separator + "TOK" + ".zip" + TFile.separator + set;
|
||||
} else {
|
||||
return imagesDir + File.separator + set;
|
||||
return imagesDir + TFile.separator + set + ".zip" + TFile.separator + set;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -148,9 +146,9 @@ public class CardImageUtils {
|
|||
String type = card.getType() != 0 ? " " + Integer.toString(card.getType()) : "";
|
||||
String name = card.getName();
|
||||
if (withCollector) {
|
||||
return getImageDir(card, imagesPath) + File.separator + name + "." + card.getCollectorId() + ".full.jpg";
|
||||
return getImageDir(card, imagesPath) + TFile.separator + name + "." + card.getCollectorId() + ".full.jpg";
|
||||
} else {
|
||||
return getImageDir(card, imagesPath) + File.separator + name + type + ".full.jpg";
|
||||
return getImageDir(card, imagesPath) + TFile.separator + name + type + ".full.jpg";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue