diff --git a/CHANGELOG.md b/CHANGELOG.md index ec727e439..f60958e3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ All notable changes to this project will be documented in this file. - Show in Simple editor context menu item for timelined items (sprites, buttons, swfs) - Simple editor - change background color - Simple editor - filters +- Simple editor - convolution filter presets ### Fixed - [#2424] DefineEditText handling of letterSpacing, font size on incorrect values diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java index c348d43c8..1a9808108 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java @@ -1204,7 +1204,7 @@ public class Timeline { if (filters != null) { for (FILTER filter : filters) { - img = filter.apply(img, unzoom, (int) deltaXMax, (int) deltaYMax, (int) Math.round(newWidth - 2 * deltaXMax), (int) Math.round(newHeight - 2 * deltaYMax)); + img = filter.apply(img, unzoom, 0, 0, newWidth, newHeight); } } if (blendMode > 1) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/CONVOLUTIONFILTER.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/CONVOLUTIONFILTER.java index 52ed841fc..52c165c05 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/CONVOLUTIONFILTER.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/CONVOLUTIONFILTER.java @@ -103,12 +103,12 @@ public class CONVOLUTIONFILTER extends FILTER { @Override public double getDeltaX() { - return ((matrixX - 1) >> 1) + 1; + return 0; } @Override public double getDeltaY() { - return ((matrixY - 1) >> 1) + 1; + return 0; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/ConvolveOp.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/ConvolveOp.java index e2b525902..01c0c67f2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/ConvolveOp.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/ConvolveOp.java @@ -142,8 +142,8 @@ public class ConvolveOp implements BufferedImageOp, RasterOp { float[] kvals = kernel.getKernelData(null); - for (int x = srcX - left; x < srcX + srcWidth + left; x++) { - for (int y = srcY - top; y < srcY + srcHeight + top; y++) { + for (int x = srcX; x < srcX + srcWidth; x++) { + for (int y = srcY; y < srcY + srcHeight; y++) { float a; if (preserveAlpha) { boolean outSide = false; @@ -157,12 +157,12 @@ public class ConvolveOp implements BufferedImageOp, RasterOp { fsrcY = srcY; outSide = true; } - if (fsrcX >= srcX + srcWidth + 1) { - fsrcX = srcX + srcWidth; + if (fsrcX >= srcX + srcWidth) { + fsrcX = srcX + srcWidth - 1; outSide = true; } - if (fsrcY >= srcY + srcHeight + 1) { - fsrcY = srcY + srcHeight; + if (fsrcY >= srcY + srcHeight) { + fsrcY = srcY + srcHeight - 1; outSide = true; } if (outSide) { @@ -212,16 +212,16 @@ public class ConvolveOp implements BufferedImageOp, RasterOp { nSrcX = srcX; outSide = true; } - if (nSrcX >= srcX + srcWidth + 1) { - nSrcX = srcX + srcWidth; + if (nSrcX >= srcX + srcWidth) { + nSrcX = srcX + srcWidth - 1; outSide = true; } if (nSrcY < srcY) { nSrcY = srcY; outSide = true; } - if (nSrcY >= srcY + srcHeight + 1) { - nSrcY = srcY + srcHeight; + if (nSrcY >= srcY + srcHeight) { + nSrcY = srcY + srcHeight - 1; outSide = true; } diff --git a/src/com/jpexs/decompiler/flash/easygui/ConvolutionPreset.java b/src/com/jpexs/decompiler/flash/easygui/ConvolutionPreset.java new file mode 100644 index 000000000..88aa20035 --- /dev/null +++ b/src/com/jpexs/decompiler/flash/easygui/ConvolutionPreset.java @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2025 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.easygui; + +import com.jpexs.decompiler.flash.types.filters.CONVOLUTIONFILTER; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +/** + * Convolution prset; + * + * @author JPEXS + */ +public class ConvolutionPreset { + + public static final ConvolutionPreset Identity = new ConvolutionPreset("identity", 3, 3, new float[]{ + 0, 0, 0, + 0, 1, 0, + 0, 0, 0 + }); + public static final ConvolutionPreset BoxBlur = new ConvolutionPreset("boxBlur", 3, 3, new float[]{ + 1, 1, 1, + 1, 1, 1, + 1, 1, 1 + }, 9); + public static final ConvolutionPreset GaussianBlur = new ConvolutionPreset("gaussianBlur", 3, 3, new float[]{ + 1, 2, 1, + 2, 4, 2, + 1, 2, 1 + }, 16); + public static final ConvolutionPreset Sharpen = new ConvolutionPreset("sharpen", 3, 3, new float[]{ + 0, -1, 0, + -1, 5, -1, + 0, -1, 0 + }); + public static final ConvolutionPreset EdgeDetectionXSobel = new ConvolutionPreset("edgeDetectionXSobel", 3, 3, new float[]{ + -1, 0, 1, + -2, 0, 2, + -1, 0, 1 + }); + public static final ConvolutionPreset EdgeDetectionYSobel = new ConvolutionPreset("edgeDetectionYSobel", 3, 3, new float[]{ + -1, -2, -1, + 0, 0, 0, + 1, 2, 1 + }); + public static final ConvolutionPreset EdgeDetectionXPrewitt = new ConvolutionPreset("edgeDetectionXPrewitt", 3, 3, new float[]{ + -1, 0, 1, + -1, 0, 1, + -1, 0, 1 + }); + public static final ConvolutionPreset EdgeDetectionYPrewitt = new ConvolutionPreset("edgeDetectionYPrewitt", 3, 3, new float[]{ + -1, -1, -1, + 0, 0, 0, + 1, 1, 1 + }); + public static final ConvolutionPreset EdgeDetectionXScharr = new ConvolutionPreset("edgeDetectionXScharr", 3, 3, new float[]{ + 3, 0, -3, + 10, 0, -10, + 3, 0, -3 + }); + public static final ConvolutionPreset EdgeDetectionYScharr = new ConvolutionPreset("edgeDetectionYScharr", 3, 3, new float[]{ + 3, 10, 3, + 0, 0, 0, + -3, -10, -3 + }); + public static final ConvolutionPreset Laplacian = new ConvolutionPreset("laplacian", 3, 3, new float[]{ + 0, -1, 0, + -1, 4, -1, + 0, -1, 0 + }); + public static final ConvolutionPreset Emboss = new ConvolutionPreset("emboss", 3, 3, new float[]{ + -2, -1, 0, + -1, 1, 1, + 0, 1, 2 + }); + public static final ConvolutionPreset Outline = new ConvolutionPreset("outline", 3, 3, new float[]{ + -1, -1, -1, + -1, 8, -1, + -1, -1, -1 + }); + public static final ConvolutionPreset MotionBlurX = new ConvolutionPreset("motionBlurX", 5, 1, new float[]{ + 1, 1, 1, 1, 1 + }, 5); + public static final ConvolutionPreset MotionBlurY = new ConvolutionPreset("motionBlurY", 1, 5, new float[]{ + 1, + 1, + 1, + 1, + 1 + }, 5); + public static final ConvolutionPreset HighPass = new ConvolutionPreset("highPass", 3, 3, new float[]{ + -1, -1, -1, + -1, 9, -1, + -1, -1, -1 + }); + private final String identifier; + + private final int matrixX; + private final int matrixY; + private final float[] matrix; + private final float divisor; + + /** + * Constructor + * + * @param identifier Convolution type identifier + * @param matrixX Matrix width + * @param matrixY Matrix height + * @param matrix Matrix + */ + public ConvolutionPreset(String identifier, int matrixX, int matrixY, float[] matrix) { + this(identifier, matrixX, matrixY, matrix, 1); + + } + + /** + * Constructor with divisor + * + * @param identifier Convolution type identifier + * @param matrixX Matrix width + * @param matrixY Matrix height + * @param matrix Matrix + * @param divisor Divisor of values + */ + public ConvolutionPreset(String identifier, int matrixX, int matrixY, float[] matrix, float divisor) { + this.identifier = identifier; + this.matrixX = matrixX; + this.matrixY = matrixY; + this.matrix = matrix; + this.divisor = divisor; + } + + /** + * Get matrix + * + * @return + */ + public float[] getMatrix() { + return matrix; + } + + /** + * Get matrix width + * + * @return + */ + public int getMatrixX() { + return matrixX; + } + + /** + * Get matrix height + * + * @return + */ + public int getMatrixY() { + return matrixY; + } + + @Override + public String toString() { + return EasyStrings.translate("convolution." + identifier); + } + + /** + * Creates new CONVOLUTIONFILTER with the preset values + * + * @return The filter + */ + public CONVOLUTIONFILTER createFilter() { + CONVOLUTIONFILTER filter = new CONVOLUTIONFILTER(); + filter.matrixX = matrixX; + filter.matrixY = matrixY; + filter.matrix = matrix.clone(); + filter.divisor = divisor; + return filter; + } + + /** + * Returns all built-in presets + * + * @return List of presets + */ + public static List getAllPresets() { + List ret = new ArrayList<>(); + for (Field field : ConvolutionPreset.class.getFields()) { + if (field.getType() == ConvolutionPreset.class) { + try { + ret.add((ConvolutionPreset) field.get(ConvolutionPreset.class)); + } catch (IllegalArgumentException | IllegalAccessException ex) { + //ignore + } + } + } + return ret; + } + + public boolean matchesFilter(CONVOLUTIONFILTER other) { + int maxX = Math.max(other.matrixX, matrixX); + int maxY = Math.max(other.matrixY, matrixY); + + int halfMaxX = (maxX - 1) / 2; + int halfMaxY = (maxY - 1) / 2; + + int halfX = (matrixX - 1) / 2; + int halfY = (matrixY - 1) / 2; + + int halfOtherX = (other.matrixX - 1) / 2; + int halfOtherY = (other.matrixY - 1) / 2; + + int halfMax = Math.max(halfMaxX, halfMaxY); + + for (int i = 0; i <= halfMax; i++) { + for (int x = -i; x <= i; x++) { + if (!compare(other, halfX + x, halfY - i, halfOtherX + x, halfOtherY - i)) { + return false; + } + if (!compare(other, halfX + x, halfY + i, halfOtherX + x, halfOtherY + i)) { + return false; + } + } + for (int y = -i; y <= i; y++) { + if (!compare(other, halfX - i, halfY + y, halfOtherX - i, halfOtherY + y)) { + return false; + } + if (!compare(other, halfX + i, halfY + y, halfOtherX + i, halfOtherY + y)) { + return false; + } + } + } + return true; + } + + private boolean compare(CONVOLUTIONFILTER other, int x1, int y1, int x2, int y2) { + int thisIndex = y1 * matrixX + x1; + int otherIndex = y2 * other.matrixX + x2; + + float val = x1 < 0 || x1 >= matrixX || y1 < 0 || y1 >= matrixY ? 0f : matrix[thisIndex] / divisor; + float otherVal = x2 < 0 || x2 >= other.matrixX || y2 < 0 || y2 >= other.matrixY ? 0f : other.matrix[otherIndex] / other.divisor; + + return val == otherVal; + } + + public static void main(String[] args) { + ConvolutionPreset p1 = new ConvolutionPreset("x1", 3, 3, new float[]{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9 + }); + + CONVOLUTIONFILTER f1 = new CONVOLUTIONFILTER(); + f1.matrixX = 5; + f1.matrixY = 5; + f1.matrix = new float[]{ + 0, 0, 0, 0, 0, + 0, 1, 2, 3, 0, + 0, 4, 5, 6, 0, + 0, 7, 8, 9, 0, + 0, 0, 0, 0, 0 + }; + + assertMatch(p1, f1); + + CONVOLUTIONFILTER f2 = new CONVOLUTIONFILTER(); + f2.matrixX = 5; + f2.matrixY = 3; + f2.matrix = new float[]{ + 0, 1, 2, 3, 0, + 0, 4, 5, 6, 0, + 0, 7, 8, 9, 0 + }; + + assertMatch(p1, f2); + + ConvolutionPreset p2 = new ConvolutionPreset("x1", 3, 3, new float[]{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9 + }, 5); + + CONVOLUTIONFILTER f3 = new CONVOLUTIONFILTER(); + f3.matrixX = 3; + f3.matrixY = 3; + f3.matrix = new float[]{ + 1 / 5f, 2 / 5f, 3 / 5f, + 4 / 5f, 5 / 5f, 6 / 5f, + 7 / 5f, 8 / 5f, 9 / 5f + }; + + assertMatch(p2, f3); + } + + private static void assertMatch(ConvolutionPreset preset, CONVOLUTIONFILTER filter) { + if (!preset.matchesFilter(filter)) { + throw new RuntimeException("Preset and filter do not match!"); + } + } + + public static ConvolutionPreset getPresetOfFilter(CONVOLUTIONFILTER filter) { + for (ConvolutionPreset preset : getAllPresets()) { + if (preset.matchesFilter(filter)) { + return preset; + } + } + return null; + } +} diff --git a/src/com/jpexs/decompiler/flash/easygui/FiltersTreeTable.java b/src/com/jpexs/decompiler/flash/easygui/FiltersTreeTable.java index f7f36c505..93d8be6e9 100644 --- a/src/com/jpexs/decompiler/flash/easygui/FiltersTreeTable.java +++ b/src/com/jpexs/decompiler/flash/easygui/FiltersTreeTable.java @@ -42,9 +42,6 @@ import de.javagl.treetable.TreeTableModel; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; -import java.awt.Cursor; -import java.awt.Dimension; -import java.awt.Graphics; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; @@ -57,14 +54,13 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Arrays; import java.util.EventObject; import java.util.List; import java.util.Objects; import java.util.Timer; import java.util.TimerTask; -import javax.swing.BorderFactory; import javax.swing.DropMode; -import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JLabel; @@ -74,7 +70,6 @@ import javax.swing.JTree; import javax.swing.ListSelectionModel; import javax.swing.TransferHandler; import javax.swing.UIManager; -import javax.swing.border.BevelBorder; import javax.swing.event.CellEditorListener; import javax.swing.event.ChangeEvent; import javax.swing.event.TreeModelEvent; @@ -94,7 +89,7 @@ import javax.swing.tree.TreePath; public class FiltersTreeTable extends JTreeTable { private List filterChangedListeners = new ArrayList<>(); - + public FiltersTreeTable() { super(new FiltersTreeTableModel(null)); getTree().setCellRenderer(new FiltersTreeCellRenderer()); @@ -1046,6 +1041,18 @@ public class FiltersTreeTable extends JTreeTable { if (o instanceof FilterField) { FilterField filterField = (FilterField) o; return new FilterValue(filterField); + } else if (o instanceof FilterName) { + FilterName filterName = (FilterName) o; + if (filterName.filter instanceof CONVOLUTIONFILTER) { + ConvolutionPreset preset = ConvolutionPreset.getPresetOfFilter((CONVOLUTIONFILTER) filterName.filter); + if (preset == null) { + return ""; + } else { + return preset; + } + } else { + return ""; + } } else { return ""; } @@ -1110,6 +1117,5 @@ public class FiltersTreeTable extends JTreeTable { public void removeTreeModelListener(TreeModelListener l) { listeners.remove(l); } - - } + } } diff --git a/src/com/jpexs/decompiler/flash/easygui/properties/ConvolutionMatrixEditor.java b/src/com/jpexs/decompiler/flash/easygui/properties/ConvolutionMatrixEditor.java index 085182bcb..357b4ddb0 100644 --- a/src/com/jpexs/decompiler/flash/easygui/properties/ConvolutionMatrixEditor.java +++ b/src/com/jpexs/decompiler/flash/easygui/properties/ConvolutionMatrixEditor.java @@ -28,7 +28,6 @@ import java.awt.FlowLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Point; -import java.awt.TextField; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; diff --git a/src/com/jpexs/decompiler/flash/easygui/properties/panels/InstancePropertiesPanel.java b/src/com/jpexs/decompiler/flash/easygui/properties/panels/InstancePropertiesPanel.java index db5d30917..ee536dcf5 100644 --- a/src/com/jpexs/decompiler/flash/easygui/properties/panels/InstancePropertiesPanel.java +++ b/src/com/jpexs/decompiler/flash/easygui/properties/panels/InstancePropertiesPanel.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.easygui.properties.panels; +import com.jpexs.decompiler.flash.easygui.ConvolutionPreset; import com.jpexs.decompiler.flash.easygui.EasyStrings; import com.jpexs.decompiler.flash.easygui.EasySwfPanel; import com.jpexs.decompiler.flash.easygui.EasyTagNameResolver; @@ -64,6 +65,7 @@ import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -72,6 +74,7 @@ import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; +import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; @@ -121,6 +124,8 @@ public class InstancePropertiesPanel extends AbstractPropertiesPanel { private boolean updating = false; + + public InstancePropertiesPanel(EasySwfPanel swfPanel, UndoManager undoManager) { super("instance"); setLayout(new BorderLayout()); @@ -382,20 +387,36 @@ public class InstancePropertiesPanel extends AbstractPropertiesPanel { filterName = filterName.substring(0, filterName.length() - "FILTER".length()); filterName = EasyStrings.translate("filter." + filterName.toLowerCase()); - JMenuItem filterMenuItem = new JMenuItem(filterName); - filterMenuItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - FILTER filter; - try { - filter = (FILTER) filterClass.getConstructor().newInstance(); - } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException ex) { - return; - } - filtersTable.addFilter(filter); - } - }); - menu.add(filterMenuItem); + if (filterClass == CONVOLUTIONFILTER.class) { + JMenu convolutionMenu = new JMenu(filterName); + for (ConvolutionPreset preset : ConvolutionPreset.getAllPresets()) { + JMenuItem filterMenuItem = new JMenuItem(preset.toString()); + filterMenuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + FILTER filter = preset.createFilter(); + filtersTable.addFilter(filter); + } + }); + convolutionMenu.add(filterMenuItem); + } + menu.add(convolutionMenu); + } else { + JMenuItem filterMenuItem = new JMenuItem(filterName); + filterMenuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + FILTER filter; + try { + filter = (FILTER) filterClass.getConstructor().newInstance(); + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException ex) { + return; + } + filtersTable.addFilter(filter); + } + }); + menu.add(filterMenuItem); + } } return menu; } @@ -1020,5 +1041,5 @@ public class InstancePropertiesPanel extends AbstractPropertiesPanel { public abstract void doColorEffectOperation(CXFORMWITHALPHA colorTransform); } - + } diff --git a/src/com/jpexs/decompiler/flash/gui/locales/EasyPanel.properties b/src/com/jpexs/decompiler/flash/gui/locales/EasyPanel.properties index c329df421..c4b3d45d7 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/EasyPanel.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/EasyPanel.properties @@ -138,4 +138,21 @@ filter.convolution = Convolution filter.dropshadow = Drop shadow filter.glow = Glow filter.gradientbevel = Gradient bevel -filter.gradientglow = Gradient glow \ No newline at end of file +filter.gradientglow = Gradient glow + +convolution.identity = Identity +convolution.boxBlur = Box blur +convolution.gaussianBlur = Gaussian blur +convolution.sharpen = Sharpen +convolution.edgeDetectionXSobel = Edge detection X (Sobel) +convolution.edgeDetectionYSobel = Edge detection Y (Sobel) +convolution.edgeDetectionXPrewitt = Edge detection X (Prewitt) +convolution.edgeDetectionYPrewitt = Edge detection Y (Prewitt) +convolution.edgeDetectionXScharr = Edge detection X (Scharr) +convolution.edgeDetectionYScharr = Edge detection Y (Scharr) +convolution.laplacian = Laplacian +convolution.emboss = Emboss +convolution.outline = Outline +convolution.motionBlurX = Motion blur X +convolution.motionBlurY = Motion blur Y +convolution.highPass = High pass \ No newline at end of file diff --git a/src/com/jpexs/decompiler/flash/gui/locales/EasyPanel_cs.properties b/src/com/jpexs/decompiler/flash/gui/locales/EasyPanel_cs.properties index 13bde49a9..00f96b8e3 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/EasyPanel_cs.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/EasyPanel_cs.properties @@ -117,4 +117,42 @@ property.instance.display.cacheAsBitmap.transparent = Pr\u016fhledn\u00e1 property.instance.display.cacheAsBitmap.opaque = S barvou #after 22.0.2 -property.document.backgroundColor = Barva pozad\u00ed \ No newline at end of file +property.document.backgroundColor = Barva pozad\u00ed + +properties.instance.header.filters = Filtry + +property.instance.filters.header.property = Vlastnost +property.instance.filters.header.value = Hodnota + +property.instance.filters.indeterminate = Neur\u010deno + +property.instance.filters = Filtry +property.instance.filters.menu.add = P\u0159idat filtr +property.instance.filters.menu.add.removeAll = Odebrat v\u0161e +property.instance.filters.menu.remove = Odebrat filtr + +filter.bevel = Reli\u00e9f +filter.blur = Rozmaz\u00e1n\u00ed +filter.colormatrix = \u00daprava barev +filter.convolution = Konvoluce +filter.dropshadow = Vr\u017een\u00fd st\u00edn +filter.glow = Z\u00e1\u0159e +filter.gradientbevel = P\u0159echodov\u00fd reli\u00e9f +filter.gradientglow = P\u0159echodov\u00e1 z\u00e1\u0159e + +convolution.identity = Identita +convolution.boxBlur = Rovnom\u011brn\u00e9 rozmaz\u00e1n\u00ed +convolution.gaussianBlur = Gaussovsk\u00e9 rozmaz\u00e1n\u00ed +convolution.sharpen = Zaost\u0159en\u00ed +convolution.edgeDetectionXSobel = Detekce hran X (Sobel) +convolution.edgeDetectionYSobel = Detekce hran Y (Sobel) +convolution.edgeDetectionXPrewitt = Detekce hran X (Prewitt) +convolution.edgeDetectionYPrewitt = Detekce hran Y (Prewitt) +convolution.edgeDetectionXScharr = Detekce hran X (Scharr) +convolution.edgeDetectionYScharr = Detekce hran Y (Scharr) +convolution.laplacian = Laplace\u016fv filtr +convolution.emboss = Vytla\u010den\u00ed +convolution.outline = Obrys +convolution.motionBlurX = Pohybov\u00e9 rozmaz\u00e1n\u00ed X +convolution.motionBlurY = Pohybov\u00e9 rozmaz\u00e1n\u00ed Y +convolution.highPass = Vysokofrekven\u010dn\u00ed filtr \ No newline at end of file