[add] gradle todo
This commit is contained in:
parent
60266646d4
commit
5a69230335
23 changed files with 840 additions and 856 deletions
36
xar/build.gradle.kts
Normal file
36
xar/build.gradle.kts
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* This file was generated by the Gradle 'init' task.
|
||||
*
|
||||
* This generated file contains a sample Java library project to get you started.
|
||||
* For more details on building Java & JVM projects, please refer to https://docs.gradle.org/9.4.1/userguide/building_java_projects.html in the Gradle documentation.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
// Apply the java-library plugin for API and implementation separation.
|
||||
`java-library`
|
||||
}
|
||||
|
||||
repositories {
|
||||
// Use Maven Central for resolving dependencies.
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Source: https://mvnrepository.com/artifact/net.coobird/thumbnailator
|
||||
implementation("net.coobird:thumbnailator:0.4.21")
|
||||
// Source: https://mvnrepository.com/artifact/org.basex/basex
|
||||
implementation("org.basex:basex:10.7")
|
||||
// Use JUnit test framework.
|
||||
testImplementation(libs.junit)
|
||||
|
||||
|
||||
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
|
||||
implementation(libs.guava)
|
||||
}
|
||||
|
||||
// Apply a specific Java toolchain to ease working on different environments.
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(11)
|
||||
}
|
||||
}
|
||||
266
xar/src/main/java/org/expkgzone58/image/Thumbs.java
Normal file
266
xar/src/main/java/org/expkgzone58/image/Thumbs.java
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
package org.expkgzone58.image;
|
||||
|
||||
import static org.basex.query.QueryError.IOERR_X;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.basex.data.Data;
|
||||
import org.basex.io.IOContent;
|
||||
import org.basex.query.QueryException;
|
||||
import org.basex.query.QueryModule;
|
||||
//import org.basex.query.func.fn.FnTrace;
|
||||
import org.basex.query.value.item.B64Lazy;
|
||||
import org.basex.query.value.node.ANode;
|
||||
import org.basex.util.Token;
|
||||
|
||||
import net.coobird.thumbnailator.ThumbnailParameter;
|
||||
import net.coobird.thumbnailator.Thumbnailator;
|
||||
import net.coobird.thumbnailator.builders.ThumbnailParameterBuilder;
|
||||
import net.coobird.thumbnailator.filters.Canvas;
|
||||
import net.coobird.thumbnailator.filters.Caption;
|
||||
import net.coobird.thumbnailator.filters.Colorize;
|
||||
import net.coobird.thumbnailator.filters.Flip;
|
||||
import net.coobird.thumbnailator.filters.ImageFilter;
|
||||
import net.coobird.thumbnailator.filters.Pipeline;
|
||||
import net.coobird.thumbnailator.filters.Rotation;
|
||||
import net.coobird.thumbnailator.filters.Watermark;
|
||||
import net.coobird.thumbnailator.geometry.AbsoluteSize;
|
||||
import net.coobird.thumbnailator.geometry.Position;
|
||||
import net.coobird.thumbnailator.geometry.Positions;
|
||||
import net.coobird.thumbnailator.geometry.Region;
|
||||
import net.coobird.thumbnailator.tasks.StreamThumbnailTask;
|
||||
|
||||
/*
|
||||
* BaseX Thumbnailator interface
|
||||
* @author andy bunce
|
||||
* @copyright Quodatum Ltd
|
||||
* @date 2017
|
||||
* @licence Apache 2
|
||||
*/
|
||||
public class Thumbs extends QueryModule{
|
||||
|
||||
public B64Lazy size(final B64Lazy inputStream, final int width, final int height)
|
||||
throws IOException, QueryException {
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(inputStream.binary(null));
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
ThumbnailParameterBuilder builder = new ThumbnailParameterBuilder();
|
||||
builder.size(width, height);
|
||||
StreamThumbnailTask task = new StreamThumbnailTask(builder.build(), is, os);
|
||||
Thumbnailator.createThumbnail(task);
|
||||
return new B64Lazy(new IOContent(os.toByteArray()), IOERR_X);
|
||||
}
|
||||
|
||||
public B64Lazy scale(final B64Lazy inputStream,
|
||||
final double xscale, final double yscale)
|
||||
throws IOException, QueryException {
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(inputStream.binary(null));
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
ThumbnailParameterBuilder builder = new ThumbnailParameterBuilder();
|
||||
builder.scale(xscale, yscale);
|
||||
StreamThumbnailTask task = new StreamThumbnailTask(builder.build(), is, os);
|
||||
Thumbnailator.createThumbnail(task);
|
||||
return new B64Lazy(new IOContent(os.toByteArray()), IOERR_X);
|
||||
}
|
||||
|
||||
public B64Lazy task(final B64Lazy inputStream, final ANode thumbnail)
|
||||
throws IOException, QueryException {
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(inputStream.binary(null));
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
ThumbnailParameter param = fromNode(thumbnail);
|
||||
StreamThumbnailTask task = new StreamThumbnailTask(param, is, os);
|
||||
Thumbnailator.createThumbnail(task);
|
||||
return new B64Lazy(new IOContent(os.toByteArray()), IOERR_X);
|
||||
}
|
||||
|
||||
// build parameters from XML
|
||||
ThumbnailParameter fromNode(final ANode node) throws QueryException, IOException {
|
||||
ThumbnailParameterBuilder builder = new ThumbnailParameterBuilder();
|
||||
for(final ANode element : node.childIter()) {
|
||||
|
||||
if (element.kind() == Data.ELEM) {
|
||||
String name = Token.string(element.name());
|
||||
// FnTrace.trace(name.getBytes(), "element: ".getBytes(), queryContext);
|
||||
switch (name) {
|
||||
|
||||
case "size":
|
||||
size(builder, element);
|
||||
break;
|
||||
|
||||
case "scale":
|
||||
scale(builder, element);
|
||||
break;
|
||||
|
||||
case "region":
|
||||
region(builder, element);
|
||||
break;
|
||||
|
||||
case "constrain":
|
||||
constrain(builder, element);
|
||||
break;
|
||||
|
||||
case "filters":
|
||||
List<ImageFilter> filters = filters(element);
|
||||
builder.filters(filters);
|
||||
break;
|
||||
|
||||
case "output":
|
||||
String format = Utils.attrib(element, "format",
|
||||
ThumbnailParameter.ORIGINAL_FORMAT);
|
||||
builder.format(format);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
void region(final ThumbnailParameterBuilder builder, final ANode node)
|
||||
throws QueryException {
|
||||
|
||||
int width = Utils.attrib(node,"width", 80);
|
||||
int height = Utils.attrib(node,"height", 80);
|
||||
Dimension d = new Dimension(width, height);
|
||||
Position pos = Utils.position(node, "position", Positions.CENTER);
|
||||
Region r = new Region(pos, new AbsoluteSize(d));
|
||||
builder.region(r);
|
||||
}
|
||||
|
||||
void constrain(final ThumbnailParameterBuilder builder, final ANode node)
|
||||
throws QueryException {
|
||||
|
||||
boolean aspect = Utils.attrib(node, "aspect", true);
|
||||
builder.keepAspectRatio(aspect);
|
||||
// FnTrace.trace(Boolean.toString(aspect).getBytes(), "constrain: ".getBytes(), queryContext);
|
||||
boolean exif = Utils.attrib(node, "exif", true);
|
||||
builder.useExifOrientation(exif);
|
||||
|
||||
boolean fit = Utils.attrib(node, "fit", true);
|
||||
builder.fitWithinDimensions(fit);
|
||||
}
|
||||
|
||||
void size(final ThumbnailParameterBuilder builder, final ANode node)
|
||||
throws QueryException {
|
||||
int width = Utils.attrib(node, "width", 80);
|
||||
int height = Utils.attrib(node, "height", 80);
|
||||
builder.size(width, height);
|
||||
}
|
||||
|
||||
void scale(final ThumbnailParameterBuilder builder, final ANode node)
|
||||
throws QueryException {
|
||||
double x = Utils.attrib(node, "x", 0.5f);
|
||||
double y = Utils.attrib(node, "y", 0.5f);
|
||||
builder.scale(x, y);
|
||||
}
|
||||
|
||||
List<ImageFilter> filters(final ANode filters) throws QueryException, IOException {
|
||||
Pipeline pipeline = new Pipeline();
|
||||
for(final ANode node : filters.childIter()) {
|
||||
if (node.kind() == Data.ELEM) {
|
||||
switch (Token.string(node.name())) {
|
||||
|
||||
case "canvas": // @width @height @color @position
|
||||
canvas(pipeline, node);
|
||||
break;
|
||||
|
||||
case "caption": //@color @position text()
|
||||
caption(pipeline, node);
|
||||
break;
|
||||
|
||||
case "colorize": //@color @alpha
|
||||
colorize(pipeline, node);
|
||||
break;
|
||||
|
||||
case "flip": //@axis
|
||||
flip(pipeline, node);
|
||||
break;
|
||||
|
||||
case "rotate": //@angle
|
||||
rotate(pipeline, node);
|
||||
break;
|
||||
|
||||
case "watermark": //@src @alpha @position
|
||||
watermark(pipeline, node);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pipeline.getFilters();
|
||||
}
|
||||
|
||||
private void watermark(final Pipeline pipeline, final ANode node)
|
||||
throws IOException, QueryException {
|
||||
ImageFilter filter;
|
||||
Position pos;
|
||||
String src = Utils.attrib(node, "src", "");
|
||||
pos = Utils.position(node, "position", Positions.BOTTOM_RIGHT);
|
||||
BufferedImage watermarkImg = ImageIO.read(new File(src));
|
||||
filter = new Watermark(pos, watermarkImg, Utils.attrib(node, "alpha", 0.5f));
|
||||
pipeline.add(filter);
|
||||
}
|
||||
|
||||
private void rotate(final Pipeline pipeline, final ANode node)
|
||||
throws QueryException {
|
||||
double angle = (double) Utils.attrib(node, "angle", 0);
|
||||
pipeline.add(Rotation.newRotator(angle));
|
||||
}
|
||||
|
||||
private void flip(final Pipeline pipeline, final ANode node) throws QueryException {
|
||||
ImageFilter filter;
|
||||
String axis = Utils.attrib(node, "axis", "vertical");
|
||||
// FnTrace.trace(axis.getBytes(), "FLIP: ".getBytes(), queryContext);
|
||||
filter = axis.equalsIgnoreCase("vertical") ? Flip.VERTICAL : Flip.HORIZONTAL;
|
||||
pipeline.add(filter);
|
||||
}
|
||||
|
||||
private void colorize(final Pipeline pipeline, final ANode node) throws QueryException {
|
||||
ImageFilter filter;
|
||||
String color;
|
||||
color = Utils.attrib(node, "color", "black");
|
||||
filter = new Colorize(Utils.stringToColor(color),
|
||||
Utils.attrib(node, "alpha", 0.0f));
|
||||
pipeline.add(filter);
|
||||
}
|
||||
|
||||
private void canvas(final Pipeline pipeline, final ANode node) throws QueryException {
|
||||
ImageFilter filter;
|
||||
String color;
|
||||
Position pos;
|
||||
int width = Utils.attrib(node, "width", 80);
|
||||
int height = Utils.attrib(node, "height", 80);
|
||||
color = Utils.attrib(node, "color", "black");
|
||||
pos = Utils.position(node, "position", Positions.CENTER);
|
||||
filter = new Canvas(width, height, pos, false, Utils.stringToColor(color));
|
||||
pipeline.add(filter);
|
||||
}
|
||||
|
||||
private void caption(final Pipeline pipeline, final ANode node) throws QueryException {
|
||||
ImageFilter filter;
|
||||
String color;
|
||||
Position pos;
|
||||
String text = Token.string(node.string());
|
||||
color = Utils.attrib(node, "color", "black");
|
||||
pos = Utils.position(node, "position", Positions.TOP_CENTER);
|
||||
String fontName = Utils.attrib(node, "font", "SansSerif");
|
||||
int size = Utils.attrib(node, "size", 14);
|
||||
int insets = Utils.attrib(node, "insets", 0);
|
||||
Font font = new Font(fontName, Font.PLAIN, size);
|
||||
filter = new Caption(text, font , Utils.stringToColor(color),
|
||||
pos, insets);
|
||||
pipeline.add(filter);
|
||||
}
|
||||
}
|
||||
73
xar/src/main/java/org/expkgzone58/image/Utils.java
Normal file
73
xar/src/main/java/org/expkgzone58/image/Utils.java
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
package org.expkgzone58.image;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.basex.query.QueryException;
|
||||
import org.basex.query.value.item.Bln;
|
||||
import org.basex.query.value.item.Dbl;
|
||||
import org.basex.query.value.item.Int;
|
||||
import org.basex.query.value.item.Item;
|
||||
import org.basex.query.value.node.ANode;
|
||||
import org.basex.util.Token;
|
||||
|
||||
import net.coobird.thumbnailator.geometry.Position;
|
||||
import net.coobird.thumbnailator.geometry.Positions;
|
||||
|
||||
public final class Utils {
|
||||
private Utils() {
|
||||
};
|
||||
// get value from attribute with default
|
||||
public static String attrib(final ANode element, final String name, final String def)
|
||||
throws QueryException {
|
||||
byte[] at = element.attribute(name.getBytes(StandardCharsets.UTF_8));
|
||||
return (at == null) ? def : Token.string(at);
|
||||
}
|
||||
|
||||
public static float attrib(final ANode element, final String name, final float def)
|
||||
throws QueryException {
|
||||
byte[] at = element.attribute(name.getBytes(StandardCharsets.UTF_8));
|
||||
return (at == null) ? def : (float) Dbl.parse(at, null);
|
||||
}
|
||||
|
||||
public static int attrib(final ANode element, final String name, final int def)
|
||||
throws QueryException {
|
||||
byte[] at = element.attribute(name.getBytes(StandardCharsets.UTF_8));
|
||||
return (at == null) ? def : Token.toInt(at);
|
||||
}
|
||||
|
||||
public static boolean attrib(final ANode element, final String name, final boolean def)
|
||||
throws QueryException {
|
||||
byte[] at = element.attribute(name.getBytes(StandardCharsets.UTF_8));
|
||||
return (boolean) ((at == null) ? def : Bln.parse(at));
|
||||
}
|
||||
|
||||
// e.g. TOP_LEFT
|
||||
public static Position position(final ANode element, final String name, final Position def) {
|
||||
byte[] at = element.attribute(name.getBytes(StandardCharsets.UTF_8));
|
||||
return (at == null) ? def : Positions.valueOf(Token.string(at));
|
||||
}
|
||||
|
||||
public static Color stringToColor(final String value) {
|
||||
if (value == null) {
|
||||
return Color.black;
|
||||
}
|
||||
try {
|
||||
// get color by hex or octal value
|
||||
return Color.decode(value);
|
||||
} catch (NumberFormatException nfe) {
|
||||
// if we can't decode lets try to get it by name
|
||||
try {
|
||||
// try to get a color by name using reflection
|
||||
final Field f = Color.class.getField(value);
|
||||
|
||||
return (Color) f.get(null);
|
||||
} catch (Exception ce) {
|
||||
// if we can't get any color return black
|
||||
return Color.black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
14
xar/src/test/java/org/example/LibraryTest.java
Normal file
14
xar/src/test/java/org/example/LibraryTest.java
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* This source file was generated by the Gradle 'init' task
|
||||
*/
|
||||
package org.example;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class LibraryTest {
|
||||
@Test public void someLibraryMethodReturnsTrue() {
|
||||
Library classUnderTest = new Library();
|
||||
assertTrue("someLibraryMethod should return 'true'", classUnderTest.someLibraryMethod());
|
||||
}
|
||||
}
|
||||
BIN
xar/thumbnailator-0.4.20.jar
Normal file
BIN
xar/thumbnailator-0.4.20.jar
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue