Browse Source

add 3 functions

master
独行之狼 3 years ago
parent
commit
edaf4c5996
  1. BIN
      fr-plugin-CharCartnoon-1.0/fr-plugin-CharCartnoon-1.0.jar
  2. BIN
      install/fr-plugin-CharCartnoon-1.0.zip
  3. 85
      src/com/fr/plugin/cool/cartnoon/FRBlurText.java
  4. 4
      src/com/fr/plugin/cool/cartnoon/FRCartnoonFunctions.java
  5. 111
      src/com/fr/plugin/cool/cartnoon/FRClockTime.java
  6. 75
      src/com/fr/plugin/cool/cartnoon/FRCustomAnimation.java
  7. 84
      src/com/fr/plugin/cool/cartnoon/FRMasaicText.java
  8. 1
      src/com/fr/plugin/cool/cartnoon/FRRotateText.java
  9. 55
      src/com/fr/plugin/cool/cartnoon/FunConstants.java
  10. 58
      src/com/fr/plugin/cool/cartnoon/TestFun.java
  11. 0
      src/com/fr/plugin/cool/cartnoon/web/resource/images/clock.png

BIN
fr-plugin-CharCartnoon-1.0/fr-plugin-CharCartnoon-1.0.jar

Binary file not shown.

BIN
install/fr-plugin-CharCartnoon-1.0.zip

Binary file not shown.

85
src/com/fr/plugin/cool/cartnoon/FRBlurText.java

@ -0,0 +1,85 @@
package com.fr.plugin.cool.cartnoon;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.Original;
import com.fr.plugin.cool.cartnoon.utils.AnimatedGifEncoder;
import com.fr.plugin.cool.cartnoon.web.ImageViewer;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.script.AbstractFunction;
import com.fr.stable.Primitive;
import com.fr.stable.fun.Authorize;
import com.jhlabs.image.BlockFilter;
import com.jhlabs.image.GaussianFilter;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@EnableMetrics
@Authorize(callSignKey = FunConstants.PLUGIN_ID)
public class FRBlurText extends AbstractFunction {
@Override
@Focus(id = FunConstants.PLUGIN_ID, text = "Plugin-Function_FRBlurText", source = Original.PLUGIN)
public Object run(Object[] args) {
if(!FunConstants.Author()){
return FunConstants.AUTHOR_ERROR;
}
if(!FunConstants.CheckArgs(args,6)){
return Primitive.ERROR_VALUE;
}
final String text = args[0].toString();
int width= Integer.parseInt(args[1].toString());
int height= Integer.parseInt(args[2].toString());
int fontSize= Integer.parseInt(args[3].toString());
int rate= Integer.parseInt(args[4].toString());
final Color color = FunConstants.TextToColor(args[5].toString());
final String id=FunConstants.GetCellId(this);
final String url="/webroot/decision/url/img?id="+id;
try {
CreateMasaicText(id,text,fontSize,rate,color);
} catch (IOException e) {
e.printStackTrace();
}
return "<img src=\""+url+"\" width=\""+width+"\" height=\""+height+"\" />";
}
private void CreateMasaicText(String id, String text, int fontSize, int rate, Color color) throws IOException {
// 读数据
AnimatedGifEncoder e = new AnimatedGifEncoder();
ByteArrayOutputStream out=new ByteArrayOutputStream();
e.start(out);
//图片之间间隔时间
e.setDelay(rate); // 1 frame per sec
//重复次数 0表示无限重复 默认不重复
e.setRepeat(0);
//添加图片
final BufferedImage image = FunConstants.ImageFromMultiText(text, fontSize, color);
for (int o=100; o>0; o--) {
e.addFrame(setFilter(image,o));
}
for (int i = 0; i < 30; i++) {
e.addFrame(image);
}
e.finish();
byte[] data = out.toByteArray();
ImageViewer.gifData.put(id,data);
}
//图像上执行高斯模糊
private BufferedImage setFilter(BufferedImage src,float radius) {
BufferedImage result = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
GaussianFilter gaussianFilter = new GaussianFilter();
gaussianFilter.setRadius(radius);
gaussianFilter.filter(src, result);
return result;
}
}

4
src/com/fr/plugin/cool/cartnoon/FRCartnoonFunctions.java

@ -18,6 +18,10 @@ public class FRCartnoonFunctions extends AbstractFunctionDefContainer {
new FunctionDef("FRRotateText", "生成旋转文本动画效果。\n参数说明:\n参数1:字符型,要旋转的文本。\n参数2:整型,文本宽度。\n参数3:整型,文本高度。\n参数4:整型,文本字号。\n参数5:整型,动画刷新频率(毫秒)。\n示例:FRRotateText(\"你好,世界\",180,180,25,300,\"ff0000\")", FRRotateText.class.getName()),
new FunctionDef("FRAnimateArraow", "生成箭头动画效果。\n参数说明:\n参数1:整型,页面占用宽度。\n参数2:整型,页面占用高度。\n参数3:文本,箭头颜色,如FF0000。\n参数4:整型,箭头粗细。\n示例:FRAnimateArraow(300,200,\"ff0000\",10)", FRAnimateArraow.class.getName()),
new FunctionDef("FRCountUp", "生成数字计数动画效果。\n参数说明:\n参数1:整型,要计数的数字。\n参数2:整型,显示宽度。\n参数3:整型,显示高度。\n参数4:整型,文本字号。\n参数5:整型,动画刷新频率(毫秒)。\n示例:FRCountUp(\"123456790\",500,100,20,100,\"ffff00\")", FRCountUp.class.getName()),
new FunctionDef("FRClockTime", "生成时钟动画效果。\n参数说明:\n参数1:文本,时间,用HH:MM表示。\n参数2:整型,显示宽度。\n参数3:整型,显示高度。\n参数4:整型,动画刷新频率(毫秒)。\n示例:FRClockTime(\"123456790\",500,100,20,100,\"ffff00\")", FRClockTime.class.getName()),
new FunctionDef("FRMasaicText", "生成马塞克动画效果。\n参数说明:\n参数1:显示的文本。\n参数2:整型,显示宽度。\n参数3:整型,显示高度。\n参数4:整型,动画刷新频率(毫秒)。\n示例:FRMasaicText(\"你好,世界\", 180, 180, 25, 100, \"ff0000\")", FRMasaicText.class.getName()),
new FunctionDef("FRBlurText", "生成高斯模糊动画效果。\n参数说明:\n参数1:显示的文本。\n参数2:整型,显示宽度。\n参数3:整型,显示高度。\n参数4:整型,动画刷新频率(毫秒)。\n示例:FRBlurText(\"你好,世界\", 180, 180, 25, 60, \"ff0000\")", FRBlurText.class.getName()),
new FunctionDef("FRCustomAnimation", "生成自定义动画效果。\n参数说明:\n参数1:文本数组,动画图片文件名或网址。\n参数2:整型,动画刷新频率(毫秒)。\n参数3:整型,显示宽度。\n参数4:整型,显示高度。\n示例:FRCustomAnimation([\"http://www.jhlabs.com/ip/filters/ChannelMixFilter.jpg\",\"http://www.jhlabs.com/ip/filters/DiffuseFilter.jpg\"], 100, 300, 300)", FRCustomAnimation.class.getName()),
};
}

111
src/com/fr/plugin/cool/cartnoon/FRClockTime.java

@ -0,0 +1,111 @@
package com.fr.plugin.cool.cartnoon;
import com.fr.base.BaseUtils;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.Original;
import com.fr.plugin.cool.cartnoon.utils.AnimatedGifEncoder;
import com.fr.plugin.cool.cartnoon.web.ImageViewer;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.script.AbstractFunction;
import com.fr.stable.Primitive;
import com.fr.stable.fun.Authorize;
import net.coobird.thumbnailator.Thumbnails;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@EnableMetrics
@Authorize(callSignKey = FunConstants.PLUGIN_ID)
public class FRClockTime extends AbstractFunction {
@Override
@Focus(id = FunConstants.PLUGIN_ID, text = "Plugin-Function_FRClockTime", source = Original.PLUGIN)
public Object run(Object[] args) {
if(!FunConstants.Author()){
return FunConstants.AUTHOR_ERROR;
}
if(!FunConstants.CheckArgs(args,4)){
return Primitive.ERROR_VALUE;
}
final String time = args[0].toString();
if(time.split(":").length!=2){
return Primitive.ERROR_VALUE;
}
int htime=Integer.parseInt(time.split(":")[0]);
if(htime>12){
htime=htime%12;
}
int mtime=Integer.parseInt(time.split(":")[1]);
int width= Integer.parseInt(args[1].toString());
int height= Integer.parseInt(args[2].toString());
int rate= Integer.parseInt(args[3].toString());
final String id=FunConstants.GetCellId(this);
final String url="/webroot/decision/url/img?id="+id;
try {
CreateClockTime(id,htime,mtime,width,rate);
} catch (IOException e) {
e.printStackTrace();
}
return "<img src=\""+url+"\" width=\""+width+"\" height=\""+height+"\" />";
}
private void CreateClockTime(String id, int htime,int mtime, int width, int rate) throws IOException {
BufferedImage bufferColck = BaseUtils.readImage("com/fr/plugin/cool/cartnoon/web/resource/images/clock.png");
final BufferedImage bufferHour = BaseUtils.readImage("com/fr/plugin/cool/cartnoon/web/resource/images/hour.png");
final BufferedImage bufferMinute = BaseUtils.readImage("com/fr/plugin/cool/cartnoon/web/resource/images/minute.png");
bufferColck=setSize(bufferColck,width,width);
AnimatedGifEncoder encoder = new AnimatedGifEncoder();
ByteArrayOutputStream out=new ByteArrayOutputStream();
encoder.start(out);
encoder.setTransparent(Color.WHITE);
encoder.setRepeat(0);
encoder.setDelay(rate);
Graphics2D g2d = bufferColck.createGraphics();
int x1=bufferColck.getWidth()/2;
int y1=bufferColck.getHeight()/2;
int hrr=htime*360/12;
int hrm=mtime*30/60;
int mr=mtime*360/60;
int o=36;
for (int i=0; i<=o; i++) {
g2d.setColor(Color.WHITE);
BufferedImage hImage1=setFilter(bufferHour,1,hrr+i*hrm/o);
BufferedImage hImage2=setSize(hImage1,bufferColck.getWidth(),bufferColck.getHeight());
g2d.fillRect(x1/2,y1/2,x1,y1);
g2d.drawImage(hImage2,null,0,0);
BufferedImage mImage1=setFilter(bufferMinute,1,i*mr/o);
BufferedImage mImage2=setSize(mImage1,bufferColck.getWidth(),bufferColck.getHeight());
g2d.drawImage(mImage2,null,0,0);
encoder.addFrame(bufferColck);
}
for (int i = 0; i <10 ; i++) {
encoder.addFrame(bufferColck);
}
g2d.dispose();
encoder.finish();
byte[] data = out.toByteArray();
ImageViewer.gifData.put(id,data);
}
//设置图像旋转缩放
private static BufferedImage setFilter(BufferedImage src, float scale, float rotate) throws IOException {
BufferedImage result = Thumbnails.of(src).scale(scale).rotate(rotate).asBufferedImage();
return result;
}
private static BufferedImage setSize(BufferedImage src, int width, int height) throws IOException {
BufferedImage result = Thumbnails.of(src).size(width,height).asBufferedImage();
return result;
}
}

75
src/com/fr/plugin/cool/cartnoon/FRCustomAnimation.java

@ -0,0 +1,75 @@
package com.fr.plugin.cool.cartnoon;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.Original;
import com.fr.plugin.cool.cartnoon.utils.AnimatedGifEncoder;
import com.fr.plugin.cool.cartnoon.web.ImageViewer;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.script.AbstractFunction;
import com.fr.stable.Primitive;
import com.fr.stable.fun.Authorize;
import com.jhlabs.image.GaussianFilter;
import net.coobird.thumbnailator.Thumbnails;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@EnableMetrics
@Authorize(callSignKey = FunConstants.PLUGIN_ID)
public class FRCustomAnimation extends AbstractFunction {
@Override
@Focus(id = FunConstants.PLUGIN_ID, text = "Plugin-Function_FRCustomAnimation", source = Original.PLUGIN)
public Object run(Object[] args) {
if(!FunConstants.Author()){
return FunConstants.AUTHOR_ERROR;
}
if(!FunConstants.CheckArgs(args,4)){
return Primitive.ERROR_VALUE;
}
String[] arrSrcImg=FunConstants.GetSrcImgFromArgs(args[0]);
int rate= Integer.parseInt(args[1].toString());
int width= Integer.parseInt(args[2].toString());
int height= Integer.parseInt(args[3].toString());
final String id=FunConstants.GetCellId(this);
final String url="/webroot/decision/url/img?id="+id;
try {
Create(id,arrSrcImg,rate,width,height);
} catch (IOException e) {
e.printStackTrace();
}
return "<img src=\""+url+"\" width=\""+width+"\" height=\""+height+"\" />";
}
private void Create(String id, String[] srcImage, int rate,int width,int height) throws IOException {
// 读数据
AnimatedGifEncoder e = new AnimatedGifEncoder();
ByteArrayOutputStream out=new ByteArrayOutputStream();
e.start(out);
//图片之间间隔时间
e.setDelay(rate); // 1 frame per sec
//重复次数 0表示无限重复 默认不重复
e.setRepeat(0);
//添加图片
int imgLen=srcImage.length;
for (int i = 0; i < imgLen; i++) {
e.addFrame(setSize(FunConstants.readImage(srcImage[i]),width,height));
}
e.finish();
byte[] data = out.toByteArray();
ImageViewer.gifData.put(id,data);
}
private BufferedImage setSize(BufferedImage src, int width, int height) throws IOException {
BufferedImage result = Thumbnails.of(src).size(width,height).asBufferedImage();
return result;
}
}

84
src/com/fr/plugin/cool/cartnoon/FRMasaicText.java

@ -0,0 +1,84 @@
package com.fr.plugin.cool.cartnoon;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.Original;
import com.fr.plugin.cool.cartnoon.utils.AnimatedGifEncoder;
import com.fr.plugin.cool.cartnoon.web.ImageViewer;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.script.AbstractFunction;
import com.fr.stable.Primitive;
import com.fr.stable.fun.Authorize;
import com.jhlabs.image.BlockFilter;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@EnableMetrics
@Authorize(callSignKey = FunConstants.PLUGIN_ID)
public class FRMasaicText extends AbstractFunction {
@Override
@Focus(id = FunConstants.PLUGIN_ID, text = "Plugin-Function_FRMasaicText", source = Original.PLUGIN)
public Object run(Object[] args) {
if(!FunConstants.Author()){
return FunConstants.AUTHOR_ERROR;
}
if(!FunConstants.CheckArgs(args,6)){
return Primitive.ERROR_VALUE;
}
final String text = args[0].toString();
int width= Integer.parseInt(args[1].toString());
int height= Integer.parseInt(args[2].toString());
int fontSize= Integer.parseInt(args[3].toString());
int rate= Integer.parseInt(args[4].toString());
final Color color = FunConstants.TextToColor(args[5].toString());
final String id=FunConstants.GetCellId(this);
final String url="/webroot/decision/url/img?id="+id;
try {
CreateMasaicText(id,text,fontSize,rate,color);
} catch (IOException e) {
e.printStackTrace();
}
return "<img src=\""+url+"\" width=\""+width+"\" height=\""+height+"\" />";
}
private void CreateMasaicText(String id, String text, int fontSize, int rate, Color color) throws IOException {
// 读数据
AnimatedGifEncoder e = new AnimatedGifEncoder();
ByteArrayOutputStream out=new ByteArrayOutputStream();
e.start(out);
//图片之间间隔时间
e.setDelay(rate); // 1 frame per sec
//重复次数 0表示无限重复 默认不重复
e.setRepeat(0);
//添加图片
final BufferedImage image = FunConstants.ImageFromMultiText(text, fontSize, color);
for (int o=36; o>0; o--) {
e.addFrame(setFilter(image,o));
}
for (int i = 0; i < 30; i++) {
e.addFrame(image);
}
e.finish();
byte[] data = out.toByteArray();
ImageViewer.gifData.put(id,data);
}
//设置图像马赛克
private BufferedImage setFilter(BufferedImage src, int blockSize) {
BufferedImage result = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
BlockFilter blockFilter = new BlockFilter();
blockFilter.setBlockSize(blockSize);
blockFilter.filter(src, result);
return result;
}
}

1
src/com/fr/plugin/cool/cartnoon/FRRotateText.java

@ -62,7 +62,6 @@ public class FRRotateText extends AbstractFunction {
//添加图片
final BufferedImage image = FunConstants.ImageFromMultiText(text, fontSize, color);
for (float i = 1; i <= 10; i++) {
// float scale=i/10;
float rotate=i*36;
e.addFrame(setFilter(image,1,rotate));
}

55
src/com/fr/plugin/cool/cartnoon/FunConstants.java

@ -1,5 +1,8 @@
package com.fr.plugin.cool.cartnoon;
import com.fr.base.BaseUtils;
import com.fr.general.FArray;
import com.fr.general.GeneralUtils;
import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginContexts;
@ -11,10 +14,17 @@ import com.fr.stable.ColumnRow;
import com.fr.stable.fun.Authorize;
import sun.font.FontDesignMetrics;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Authorize(callSignKey = FunConstants.PLUGIN_ID)
public class FunConstants {
@ -147,4 +157,49 @@ public class FunConstants {
String id=strCol+intRow;
return id;
}
static BufferedImage readImage(Object file) {
BufferedImage res=null;
// if (file instanceof BufferedImage) {
// return (BufferedImage) file;
// }
String filename = file.toString();
if(isHttpUrl(filename)){
res= BaseUtils.readImage(filename);
}else {
File fn = new File(filename);
try {
ImageIO.setUseCache(false);
res = ImageIO.read(fn);
} catch (IOException e) {
throw new Error("File:" + filename + InterProviderFactory.getProvider().getLocText("Plugin.Function.ImagProcess_ReadImageError"));
}
}
return res;
}
static boolean isHttpUrl(String urls) {
String regex = "(((https|http)?://)?([a-z0-9]+[.])|(www.))"
+ "\\w+[.|\\/]([a-z0-9]{0,})?[[.]([a-z0-9]{0,})]+((/[\\S&&[^,;\u4E00-\u9FA5]]+)+)?([.][a-z0-9]{0,}+|/?)";//设置正则表达式
Pattern pat = Pattern.compile(regex.trim());//对比
Matcher mat = pat.matcher(urls.trim());
return mat.matches();//判断是否匹配
}
static String[] GetSrcImgFromArgs(Object arg){
if (arg instanceof FArray) {
FArray fa = (FArray) arg;
int len = fa.length();
String[] result = new String[len];
for (int j = 0; j < len; j++) {
Object fao = fa.elementAt(j);
String title = GeneralUtils.objectToString(fao);
if (title != null && title != "" && title.length() != 0) {
result[j] = title;
}
}
return result;
}
return null;
}
}

58
src/com/fr/plugin/cool/cartnoon/TestFun.java

@ -4,6 +4,7 @@ import com.fr.base.BaseUtils;
import com.fr.plugin.cool.cartnoon.utils.AnimatedGifEncoder;
import com.fr.plugin.cool.cartnoon.utils.DrawValueLine;
import com.fr.plugin.cool.cartnoon.web.ImageViewer;
import com.jhlabs.image.BlockFilter;
import javafx.scene.shape.Shape3D;
import net.coobird.thumbnailator.Thumbnails;
@ -14,64 +15,35 @@ import java.awt.image.BufferedImage;
import java.io.*;
public class TestFun {
public static final int SIZE = 200;
public static void main(String args[]) throws Exception {
// BufferedImage image1 = new BufferedImage(500, 500, BufferedImage.TYPE_4BYTE_ABGR);
// DrawValueLine drawValueLine= new DrawValueLine(image1,50,50,250,50,24.0);
// drawValueLine.DrawLine(10);
// final BufferedImage image = BaseUtils.readImage("com/fr/plugin/cool/cartnoon/web/resource/images/click.png");
BufferedImage image = BaseUtils.readImage("I:\\Users\\Administrator\\2020\\report-starter-10\\plugin-function-char-cartnoon\\src\\com\\fr\\plugin\\cool\\cartnoon\\web\\resource\\images\\click.png");
final BufferedImage hour = BaseUtils.readImage("I:\\Users\\Administrator\\2020\\report-starter-10\\plugin-function-char-cartnoon\\src\\com\\fr\\plugin\\cool\\cartnoon\\web\\resource\\images\\hour.png");
final BufferedImage minute = BaseUtils.readImage("I:\\Users\\Administrator\\2020\\report-starter-10\\plugin-function-char-cartnoon\\src\\com\\fr\\plugin\\cool\\cartnoon\\web\\resource\\images\\minute.png");
image=setSize(image,300,300);
BufferedImage image=BaseUtils.readImage("http://www.jhlabs.com/shadowheader.jpg");
AnimatedGifEncoder encoder = new AnimatedGifEncoder();
encoder.start("d:\\out.gif");
encoder.setTransparent(Color.WHITE);
encoder.setRepeat(0);
encoder.setDelay(100);
Graphics2D g2d = image.createGraphics();
int x1=image.getWidth()/2;
int y1=image.getHeight()/2;
int x2=x1;
int y2=y1/2;
int htime=9;
int mtime=20;
int hr=htime*(360+30)/12;
int hrr=htime*360/12;
int hrm=mtime*30/60;
int mr=mtime*360/60;
System.out.printf("\nhrm:"+hrm);
int o=36;
for (int i=0; i<=o; i++) {
g2d.setColor(Color.WHITE);
BufferedImage hImage1=setFilter(hour,1,hrr+i*hrm/o);
BufferedImage hImage2=setSize(hImage1,image.getWidth(),image.getHeight());
g2d.fillRect(x1/2,y1/2,x1,y1);
g2d.drawImage(hImage2,null,0,0);
int o=36;
for (; o>0; o--) {
BufferedImage mImage1=setFilter(minute,1,i*mr/o);
BufferedImage mImage2=setSize(mImage1,image.getWidth(),image.getHeight());
g2d.drawImage(mImage2,null,0,0);
encoder.addFrame(image);
encoder.addFrame(setFilter(image,o));
}
for (int i = 0; i <10 ; i++) {
for (int i = 0; i < 30; i++) {
encoder.addFrame(image);
}
g2d.dispose();
encoder.finish();
}
//设置图像旋转缩放
private static BufferedImage setFilter(BufferedImage src, float scale, float rotate) throws IOException {
BufferedImage result = Thumbnails.of(src).scale(scale).rotate(rotate).asBufferedImage();
return result;
}
private static BufferedImage setSize(BufferedImage src, int width, int height) throws IOException {
BufferedImage result = Thumbnails.of(src).size(width,height).asBufferedImage();
//设置图像马赛克
private static BufferedImage setFilter(BufferedImage src, int blockSize) {
BufferedImage result = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
BlockFilter blockFilter = new BlockFilter();
blockFilter.setBlockSize(blockSize);
blockFilter.filter(src, result);
return result;
}
}

0
src/com/fr/plugin/cool/cartnoon/web/resource/images/click.png → src/com/fr/plugin/cool/cartnoon/web/resource/images/clock.png

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Loading…
Cancel
Save