Могу ли я сказать, каким был тип файла BufferedImage изначально?
в моем коде, у меня есть BufferedImage, который был загружен с ImageIO класс вот так:
BufferedImage image = ImageIO.read(new File (filePath);
позже, я хочу сохранить его в массив байтов, но ImageIO.write
метод требует, чтобы я выбрал формат GIF, PNG или JPG для записи моего изображения как (как описано в учебнике здесь).
Я хочу выбрать тот же тип файла исходного изображения. Если изображение изначально было GIF, я не хочу дополнительных накладных расходов сохранение его как PNG. Но если изображение изначально было PNG, я не хочу терять прозрачность и такие, сохраняя его как JPG или GIF. Есть ли способ определить из BufferedImage, каким был исходный формат файла?
Я знаю, что я мог бы просто проанализировать путь к файлу, когда я загружаю изображение, чтобы найти расширение и просто сохранить его на потом, но в идеале я хотел бы сделать это прямо из BufferedImage.
3 ответов
как говорит @JarrodRoberson,BufferedImage
не имеет " формата "(т. е. нет формата файла, он имеет один из нескольких форматов пикселей или пиксельные"макеты"). Я не знаю Apache Tika, но я думаю, что его решение также будет работать.
однако, если вы предпочитаете использовать только ImageIO
и не добавляя новых зависимостей в свой проект, вы можете написать что-то вроде:
ImageInputStream input = ImageIO.createImageInputStream(new File(filePath));
try {
Iterator<ImageReader> readers = ImageIO.getImageReaders(input);
if (readers.hasNext()) {
ImageReader reader = readers.next();
try {
reader.setInput(input);
BufferedImage image = reader.read(0); // Read the same image as ImageIO.read
// Do stuff with image...
// When done, either (1):
String format = reader.getFormatName(); // Get the format name for use later
if (!ImageIO.write(image, format, outputFileOrStream)) {
// ...handle not written
}
// (case 1 done)
// ...or (2):
ImageWriter writer = ImageIO.getImageWriter(reader); // Get best suitable writer
try {
ImageOutputStream output = ImageIO.createImageOutputStream(outputFileOrStream);
try {
writer.setOutput(output);
writer.write(image);
}
finally {
output.close();
}
}
finally {
writer.dispose();
}
// (case 2 done)
}
finally {
reader.dispose();
}
}
}
finally {
input.close();
}
можно инкапсулировать BufferedImage и связанные данные в экземпляре (экземплярах) класса следующим образом:
final public class TGImage
{
public String naam;
public String filename;
public String extension;
public int layerIndex;
public Double scaleX;
public Double scaleY;
public Double rotation;
public String status;
public boolean excluded;
public BufferedImage image;
public ArrayList<String> history = new ArrayList<>(5);
public TGImage()
{
naam = "noname";
filename = "";
extension ="";
image = null;
scaleX = 0.0;
scaleY = 0.0;
rotation = 0.0;
status = "OK";
excluded = false;
layerIndex = 0;
addHistory("Created");
}
final public void addHistory(String str)
{
history.add(TGUtil.getCurrentTimeStampAsString() + " " + str);
}
}
а затем используйте его так:
public TGImage loadImage()
{
TGImage imgdat = new TGImage();
final JFileChooser fc = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter("Image Files", "jpg", "png", "gif", "tif");
fc.setFileFilter(filter);
fc.setCurrentDirectory(new File(System.getProperty("user.home")));
int result = fc.showOpenDialog(this); // show file chooser
if (result == JFileChooser.APPROVE_OPTION)
{
File file = fc.getSelectedFile();
System.out.println("Selected file extension is " + TGUtil.getFileExtension(file));
if (TGUtil.isAnImageFile(file))
{
//System.out.println("This is an Image File.");
try
{
imgdat.image = ImageIO.read(file);
imgdat.filename = file.getName();
imgdat.extension = TGUtil.getFileExtension(file);
info("image has been loaded from file:" + imgdat.filename);
} catch (IOException ex)
{
Logger.getLogger(TGImgPanel.class.getName()).log(Level.SEVERE, null, ex);
imgdat.image = null;
info("File not loaded IOexception: img is null");
}
} else
{
imgdat = null;
info("File not loaded: The requested file is not an image File.");
}
}
return imgdat;
}
тогда у вас есть все необходимое вместе в экземпляре(экземплярах) TGImage. и, возможно, использовать его в imagelist так:
ArrayList<TGImage> images = new ArrayList<>(5);