Added: #2504 WebP image format for export/import (not animated)

Limitation: It's not available on Mac x86-64 platform
This commit is contained in:
Jindra Petřík
2025-08-10 18:45:12 +02:00
parent d8dc85109b
commit 2df87d1a0a
29 changed files with 344 additions and 30 deletions
@@ -210,8 +210,7 @@ alias /?
-format <format> (optional, html is default) Selects output format
<format> is currently only html
-locale <locale> (optional) Override default locale
<locale> is localization identifier, en for english for example
<format> is currently only html
<locale> is localization identifier, en for english for example
-getInstanceMetadata -instance <instanceName> [-outputFormat <outputFormat>] \
[-key <key> ] [-datafile <datafile>] <swffile>
@@ -324,8 +323,12 @@ Pre-options:
shape:png - PNG format for Shapes
shape:canvas - HTML5 Canvas format for Shapes
shape:bmp - BMP format for Shapes
shape:webp - WEBP format for Shapes
morphshape:svg - SVG format for MorphShapes
morphshape:canvas - HTML5 Canvas format for MorphShapes
morpshape:png_start_end - PNG start-end format for MorphShapes
morpshape:bmp_start_end - BMP start-end format for MorphShapes
morpshape:webp_start_end - WEBP start-end format for MorphShapes
frame:png - PNG format for Frames
frame:gif - GIF format for Frames
frame:avi - AVI format for Frames
@@ -333,6 +336,7 @@ Pre-options:
frame:canvas - HTML5 Canvas format for Frames
frame:pdf - PDF format for Frames
frame:bmp - BMP format for Frames
frame:webp - WEBP format for Frames
sprite:png - PNG format for Sprites
sprite:gif - GIF format for Sprites
sprite:avi - AVI format for Sprites
@@ -340,14 +344,17 @@ Pre-options:
sprite:canvas - HTML5 Canvas format for Sprites
sprite:pdf - PDF format for Sprites
sprite:bmp - BMP format for Sprites
sprite:webp - WEBP format for Sprites
button:png - PNG format for Buttons
button:svg - SVG format for Buttons
button:bmp - BMP format for Buttons
button:webp - WEBP format for Buttons
image:png_gif_jpeg - PNG/GIF/JPEG format for Images
image:png - PNG format for Images
image:jpeg - JPEG format for Images
image:bmp - BMP format for Images
image:png_gif_jpeg_alpha - PNG/GIF/JPEG+ALPHA format for Images
image:webp - WEBP format for Images
text:plain - Plain text format for Texts
text:formatted - Formatted text format for Texts
text:svg - SVG format for Texts
@@ -59,10 +59,14 @@ import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
@@ -141,7 +145,7 @@ public class ExportDialog extends AppDialog {
ButtonExportMode.class
};
private final JComboBox[] combos;
private final JComboBox<ComboValue>[] combos;
private final JCheckBox[] checkBoxes;
@@ -157,9 +161,8 @@ public class ExportDialog extends AppDialog {
public <E> E getValue(Class<E> option) {
for (int i = 0; i < optionClasses.length; i++) {
if (option == optionClasses[i]) {
E[] values = option.getEnumConstants();
return values[combos[i].getSelectedIndex()];
if (option == optionClasses[i]) {
return (E) ((ComboValue) combos[i].getSelectedItem()).value;
}
}
@@ -199,10 +202,9 @@ public class ExportDialog extends AppDialog {
private void saveConfig() {
StringBuilder cfg = new StringBuilder();
for (int i = 0; i < optionNames.length; i++) {
int selIndex = combos[i].getSelectedIndex();
Object val = ((ComboValue) combos[i].getSelectedItem()).value;
Class c = optionClasses[i];
Object[] vals = c.getEnumConstants();
String key = optionNames[i] + "." + vals[selIndex].toString().toLowerCase(Locale.ENGLISH);
String key = optionNames[i] + "." + val.toString().toLowerCase(Locale.ENGLISH);
if (i > 0) {
cfg.append(",");
}
@@ -321,17 +323,31 @@ public class ExportDialog extends AppDialog {
for (int i = 0; i < optionNames.length; i++) {
Class c = optionClasses[i];
Object[] vals = c.getEnumConstants();
String[] names = new String[vals.length];
List<ComboValue> namesList = new ArrayList<>();
int itemIndex = -1;
for (int j = 0; j < vals.length; j++) {
try {
Method availableMethod = c.getMethod("available");
if (!(Boolean)availableMethod.invoke(vals[j]))
{
continue;
}
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
//ignore
}
//ignore
//ignore
String key = optionNames[i] + "." + vals[j].toString().toLowerCase(Locale.ENGLISH);
if (exportFormats.contains(key)) {
itemIndex = j;
}
names[j] = translate(key);
namesList.add(new ComboValue(vals[j], translate(key)));
}
ComboValue[] names = namesList.toArray(new ComboValue[0]);
combos[i] = new JComboBox<>(names);
if (itemIndex > -1) {
combos[i].setSelectedIndex(itemIndex);
@@ -494,4 +510,19 @@ public class ExportDialog extends AppDialog {
setVisible(true);
return result;
}
private class ComboValue {
public Object value;
public String text;
public ComboValue(Object value, String text) {
this.value = value;
this.text = text;
}
@Override
public String toString() {
return text;
}
}
}
@@ -16,14 +16,21 @@
*/
package com.jpexs.decompiler.flash.gui;
import com.jpexs.decompiler.flash.helpers.ImageHelper;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.helpers.Helper;
import dev.matrixlab.webp4j.WebPCodec;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
@@ -87,9 +94,26 @@ public class FileChooserImagePreview extends JComponent
return;
}
ImageIcon tmpIcon = new ImageIcon(file.getPath());
BufferedImage img = null;
if (file.getPath().toLowerCase().endsWith(".webp")) {
if (ImageFormat.WEBP.available()) {
try {
img = WebPCodec.decodeImage(Helper.readFile(file.getAbsolutePath()));
} catch (IOException ex) {
//ignore
}
}
} else {
try(FileInputStream fis = new FileInputStream(file)) {
img = ImageHelper.read(fis);
} catch (IOException ex) {
//ignore
}
}
if (img != null) {
ImageIcon tmpIcon = new ImageIcon(img);
if (tmpIcon != null) {
if (tmpIcon.getImageLoadStatus() == MediaTracker.COMPLETE) {
if (tmpIcon.getIconWidth() > PREVIEW_SIZE) {
thumbnail = new ImageIcon(tmpIcon.getImage().getScaledInstance(PREVIEW_SIZE, -1, Image.SCALE_DEFAULT));
@@ -182,6 +182,7 @@ import com.jpexs.decompiler.flash.tags.base.SymbolClassTypeTag;
import com.jpexs.decompiler.flash.tags.base.TextImportErrorHandler;
import com.jpexs.decompiler.flash.tags.base.TextTag;
import com.jpexs.decompiler.flash.tags.base.UnsupportedSamplingRateException;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.tags.gfx.DefineExternalStreamSound;
import com.jpexs.decompiler.flash.tags.text.TextParseException;
import com.jpexs.decompiler.flash.timeline.AS3Package;
@@ -5253,10 +5254,19 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
//}
}
if (ti0 instanceof ImageTag) {
file = showImportFileChooser("filter.images|*.jpg;*.jpeg;*.gif;*.png;*.bmp", true, "importimage");
String filters = "*.jpg;*.jpeg;*.gif;*.png;*.bmp";
if (ImageFormat.WEBP.available()) {
filters += ";*.webp";
}
file = showImportFileChooser("filter.images|" + filters, true, "importimage");
}
if (ti0 instanceof ShapeTag) {
file = showImportFileChooser("filter.images|*.jpg;*.jpeg;*.gif;*.png;*.bmp;*.svg", true, "importshape");
String filters = "*.jpg;*.jpeg;*.gif;*.png;*.bmp";
if (ImageFormat.WEBP.available()) {
filters += ";*.webp";
}
filters += ";*.svg";
file = showImportFileChooser("filter.images|" + filters, true, "importshape");
}
if (ti0 instanceof MorphShapeTag) {
return replaceMorphShape((MorphShapeTag) ti0, create, true);
@@ -17,6 +17,7 @@ shapes = Shapes
shapes.svg = SVG
shapes.png = PNG
shapes.bmp = BMP
shapes.webp = WEBP
shapes.canvas = HTML5 Canvas
shapes.swf = SWF
texts = Texts
@@ -28,6 +29,7 @@ images.png_gif_jpeg=PNG/GIF/JPEG
images.png = PNG
images.jpeg = JPEG
images.bmp = BMP
images.webp = WEBP
movies = Movies
movies.flv = FLV (No audio)
sounds = Sounds
@@ -56,6 +58,7 @@ morphshapes.swf = SWF
morphshapes.bmp_start_end=BMP (start, end)
morphshapes.png_start_end=PNG (start, end)
morphshapes.svg_start_end=SVG (start, end)
morphshapes.webp_start_end=WEBP (start, end)
frames = Frames
frames.png = PNG
frames.gif = GIF
@@ -64,6 +67,7 @@ frames.svg = SVG
frames.canvas = HTML5 Canvas
frames.pdf = PDF
frames.bmp = BMP
frames.webp = WEBP
frames.swf = SWF
sprites = Sprites
sprites.png = PNG
@@ -73,11 +77,13 @@ sprites.svg = SVG
sprites.canvas = HTML5 Canvas
sprites.pdf = PDF
sprites.bmp = BMP
sprites.webp = WEBP
sprites.swf = SWF
buttons = Buttons
buttons.png = PNG
buttons.svg = SVG
buttons.bmp = BMP
buttons.webp = WEBP
buttons.swf = SWF
fonts = Fonts
fonts.ttf = TTF