diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8d39678
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+target
+*.bat
+*.cmd
+*.png
+*.mkv
+nbactions.xml
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..8d4b554
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,26 @@
+
+
+ 4.0.0
+ com.tmworks
+ telopGenerator
+ 1.0.0
+ jar
+
+
+ club.tmworks
+ telopeditor
+ 1.0
+
+
+ com.tmworks
+ lyricsmovie
+
+
+
+
+
+ UTF-8
+ 11
+ 11
+
+
\ No newline at end of file
diff --git a/src/main/java/com/tmworks/telopgenerator/PngGenerator.java b/src/main/java/com/tmworks/telopgenerator/PngGenerator.java
new file mode 100644
index 0000000..187d6f6
--- /dev/null
+++ b/src/main/java/com/tmworks/telopgenerator/PngGenerator.java
@@ -0,0 +1,230 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
+ */
+package com.tmworks.telopgenerator;
+
+import club.tmworks.telopeditor.model.ProjectInfo;
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.font.FontRenderContext;
+import java.awt.font.TextLayout;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.ConvolveOp;
+import java.awt.image.Kernel;
+import java.io.File;
+import java.io.IOException;
+import java.util.function.Supplier;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.imageio.ImageIO;
+
+/**
+ *
+ * @author bythe
+ */
+public class PngGenerator {
+
+ int width = 1920;
+ int height = 1080;
+
+ int fontSize = 96;
+
+ int shadingSize = 30;
+
+ Color fontColor = Color.white;
+
+ Color shadingColor = Color.BLACK;
+
+ Font fontFront = new Font("HGP明朝E", Font.PLAIN, fontSize);
+ Font fontShading = new Font("HGP明朝E", Font.PLAIN, fontSize);
+
+ private String locationVertical = "";
+ private String locationHorizontal = "";
+
+ public PngGenerator() {
+
+ }
+
+ public void setLocation(String vertical, String horizontal) {
+ this.locationVertical = vertical;
+ this.locationHorizontal = horizontal;
+ }
+
+ public void setShadingSize(int size) {
+ this.shadingSize = size;
+ }
+
+ public void setFontFront(String fontName, int fontStyle, int fontSize) {
+ this.fontFront = new Font(fontName, fontStyle, fontSize);
+ }
+
+ public void setFontShading(String fontName, int fontStyle, int fontSize) {
+ this.fontShading = new Font(fontName, fontStyle, fontSize);
+ }
+
+ public void setFontName(String fontName) {
+ this.fontFront = new Font(fontName, this.fontFront.getStyle(), this.fontSize);
+ this.fontShading = new Font(fontName, this.fontFront.getStyle(), this.fontSize);
+ }
+
+ public void setSize(int width, int height) {
+ this.width = width;
+ this.height = height;
+ }
+
+ public void setFontSize(int size) {
+ this.fontSize = size;
+ this.fontFront = this.fontFront.deriveFont(Float.valueOf(this.fontSize));
+ this.fontShading = this.fontFront.deriveFont(Float.valueOf(this.fontSize));
+ }
+
+ public void generate(String fileName, String text) {
+ try {
+ BufferedImage img = this.getTelopImage(text);
+
+ ImageIO.write(img, "png", new File(fileName));
+ } catch (IOException e) {
+ Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, (Supplier) e);
+ }
+ }
+
+ /**
+ * センタリング時の描画開始点X座標
+ *
+ * @param text
+ * @return
+ */
+ public float getCenteringLocationX(String text) {
+ if (text.length() < 1) {
+ return 0f;
+ }
+ BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
+ Graphics2D g2d = img.createGraphics();
+ FontRenderContext frc = g2d.getFontRenderContext();
+ TextLayout layout = new TextLayout(text, this.fontFront, frc);
+ Rectangle2D rect = layout.getBounds();
+
+ float margine = 0f;
+ switch (this.locationHorizontal) {
+ case ProjectInfo.HORIZONTAL_LEFT:
+ margine = (float) rect.getWidth() / text.length();
+ break;
+ case ProjectInfo.HORIZONTAL_CENTER:
+ margine = ((float) (this.width - rect.getWidth())) / 2.0f;
+ break;
+ case ProjectInfo.HORIZOTAL_RIGHT:
+ margine = (float) this.width - (float) rect.getWidth() - (float) rect.getWidth() / (float) text.length();
+ break;
+ }
+ return margine;
+ }
+
+ public float getCenteringLocationY(String text) {
+ if (text.length() < 1) {
+ return 0f;
+ }
+ BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
+ Graphics2D g2d = img.createGraphics();
+ FontRenderContext frc = g2d.getFontRenderContext();
+ TextLayout layout = new TextLayout(text, this.fontFront, frc);
+ Rectangle2D rect = layout.getBounds();
+
+ float margine = 0f;
+ switch (this.locationVertical) {
+ case ProjectInfo.VERTICAL_TOP:
+ margine = (float) rect.getHeight() * 2.0f;
+ break;
+ case ProjectInfo.VERTICAL_CENTER:
+ margine = ((float) (img.getHeight() - rect.getHeight())) / 2.0f;
+ margine = (float) rect.getHeight() + margine;
+ break;
+ case ProjectInfo.VERTICAL_BOTTOM:
+ margine = ((float) (img.getHeight()) - (float) rect.getHeight() * 1.5f);
+ break;
+ }
+
+ return margine;
+ }
+
+ private void modfySize(String text) {
+ if (text.length() < 1) {
+ return;
+ }
+ BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
+ Graphics2D g2d = img.createGraphics();
+ FontRenderContext frc = g2d.getFontRenderContext();
+ TextLayout layout = new TextLayout(text, this.fontFront, frc);
+ Rectangle2D rect = layout.getBounds();
+ if (this.width < rect.getWidth() + this.shadingSize * 2) {
+ this.width = (int) rect.getWidth() + this.shadingSize * 2;
+ }
+ if (this.height < rect.getHeight() + this.shadingSize * 2) {
+ this.height = (int) rect.getHeight() + this.shadingSize * 2;
+ }
+ }
+
+ public BufferedImage getTelopImage(String text) {
+
+ this.modfySize(text);
+
+ BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
+
+ Graphics2D g2d = img.createGraphics();
+ g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
+ Rectangle2D.Double rect = new Rectangle2D.Double(0, 0, img.getHeight(), img.getHeight());
+ g2d.fill(rect);
+ g2d.setPaintMode();
+ g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
+ RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+
+ // ぼかした文字背景
+ g2d.setColor(this.shadingColor);
+ g2d.setFont(this.fontShading);
+ g2d.drawString(text, this.getCenteringLocationX(text), this.getCenteringLocationY(text)); //文字を書く
+ img = this.getShadingImage(img, this.shadingSize, 100f);
+
+ // テロップ文字
+ g2d = img.createGraphics();
+ g2d.setColor(this.fontColor);
+ g2d.setFont(this.fontFront);
+ g2d.drawString(text, this.getCenteringLocationX(text), this.getCenteringLocationY(text)); //文字を書く
+ img = this.getShadingImage(img, 3, 10f);
+ return img;
+ }
+
+ /**
+ * ぼかし
+ *
+ * @param im
+ * @param shadingSize
+ * @param shardeRate
+ * @return
+ */
+ public BufferedImage getShadingImage(BufferedImage im, int shadingSize, float shardeRate) {
+
+ int ssize = shadingSize * shadingSize;
+
+ float[] data = new float[ssize];
+ for (int i = 0; i < data.length; i++) {
+ data[i] = 1 / shardeRate;
+ }
+
+ int w1 = im.getWidth(), h1 = im.getHeight();
+ BufferedImage im2 = new BufferedImage(w1, h1, im.getType());
+
+ Kernel kernel = new Kernel(shadingSize, shadingSize, data);
+ ConvolveOp op = new ConvolveOp(kernel);
+ op.filter(im, im2);
+
+ return im2;
+ }
+
+ public static void main(String[] args) {
+ new PngGenerator().generate("sample.png", "中々いいでんな。");
+ }
+}