今回は動画編集のエフェクトを
プログラミングで作成するという
試みをしようと思います。
ほとんどの言語で
エフェクトを作成出来ます。
動画編集ソフトの
「グラデーションワイプ」機能で
使う事が出来るグレースケール画像を
作成する事を目標にします。
premiere pro cc で
動作することを確認しております。
この記事を参考にすると
どんなエフェクトを作れるかについては
下記のサイトに成果物があります。
成果物は下記のサイトから
ダウンロードする事も出来ます。
作成例
やる事は 1600 × 900 の
グレースケール画像を作成する事です。
グレースケール画像を
グラデーションワイプで設定すると
黒い部分から白い部分にかけて
フェードしていきます。
そのサイズならば 16:9 の動画に使用できます。
16:9 は youtube 動画の作成に向いています。
ここでは java C♯ Unity での
作成例を載せます。
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Shape;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Exec3 {
public static void main(String[] args) throws Exception {
int width = 1600;
int height = 900;
BufferedImage bufferImage=new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);//Buffer用イメージを作成
Graphics2D g2=bufferImage.createGraphics();//描画用のGraphics2D型変数g2を取得
g2.setColor(new Color(255, 255, 255));
g2.fillRect(0, 0, width, height);
/*
for(int i = 0; i < width; i++){
g2.setColor(new Color(255 * i / width, 255 * i / width, 255 * i / width));
for(int j = 0; j < height; j++){
g2.drawLine(i, j, i, j);
}
}
*/
/*
//円
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
float posX = width * 1 / 4;
float posY = height * 2 / 3;
float f = (float)Math.pow(Math.pow(posX - i, 2) + Math.pow(posY - j, 2), 0.5f);
f = Math.min(255, f / 5);
int num = (int)f;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
*/
/*
//円逆
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
float posX = width * 1 / 4;
float posY = height * 2 / 3;
float f = (float)Math.pow(Math.pow(posX - i, 2) + Math.pow(posY - j, 2), 0.5f);
f = Math.min(255, f / 5);
f = 255 - f;
int num = (int)f;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
*/
/*
//四角形斜め
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
float posX = width * 1 / 4;
float posY = height * 2 / 3;
float f = Math.abs(posX - i) + Math.abs(posY - j);
f = Math.min(255, f / 7);
f = Math.max(0, f);
int num = (int)f;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
*/
/*
//四角形斜め逆
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
float posX = width * 1 / 4;
float posY = height * 2 / 3;
float f = Math.abs(posX - i) + Math.abs(posY - j);
f = Math.min(255, f / 7);
f = Math.max(0, f);
f = 255 - f;
int num = (int)f;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
*/
/*
//斜め扉
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
float posX = width * 1 / 4;
float posY = height * 2 / 3;
float f = Math.abs(posX + posY - i - j);
f = Math.min(255, f / 7);
f = Math.max(0, f);
int num = (int)f;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
*/
/*
//斜め扉逆
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
float posX = width * 1 / 4;
float posY = height * 2 / 3;
float f = Math.abs(posX + posY - i - j);
f = Math.min(255, f / 7);
f = Math.max(0, f);
f = 255 - f;
int num = (int)f;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
*/
/* 波スライド
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
double f = (height - j) + Math.sin(Math.toRadians(i / 2f)) * 60;
f = Math.min(255, f / 3.5f);
f = Math.max(0, f);
int num = (int)f;
num = 255 - num;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
ImageIO.write(bufferImage, "png", new File("波スライド.png"));
*/
/*
//5角形
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
float posX = width * 3 / 4;
float posY = height * 1 / 3;
double f = Math.abs(posX - i) + Math.abs(posY - j);
f = f * (0.6 + 0.4 * Math.sin(5 * Math.atan2(posX - i, posY - j)));
f = Math.min(255, f / 7);
f = Math.max(0, f);
int num = (int)f;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
*/
/*
//5角形亜種
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
float f = (Math.abs(posX - i) + Math.abs(posY - j)) / 1.5f * (Math.abs((float)Math.sin(2.5 * Math.atan2(posY - j, posX - i))) + 1);
f = Math.abs(f);
f = Math.min(255, f / 7);
int num = (int)f;
//num = 255 - num;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
*/
/*
//花
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
float posX = width * 1 / 4;
float posY = height * 2 / 3;
double f = Math.abs(posX - i) + Math.abs(posY - j);
f = f * ((0.3 + 0.2 * Math.abs(Math.tan(4 * Math.atan2(posX - i, posY - j))) + (0.3 + 0.2 * Math.abs(Math.atan2(posY - j, posX - i)))));
f = Math.min(255, f / 7);
f = Math.max(0, f);
int num = (int)f;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
*/
/*
//前半花 後半スライド
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
float posX = width * 1 / 4;
float posY = height * 2 / 3;
double f = Math.abs(posX - i) + Math.abs(posY - j);
f = f * ((0.3 + 0.2 * Math.abs(Math.tan(4 * Math.atan2(posX - i, posY - j))) + (0.3 + 0.2 * Math.abs(Math.atan2(posY - j, posX - i)))));
f = Math.min(255, f / 7);
f = Math.max(0, f);
f -= 255 / 2 * i / width;
f = Math.min(255, f);
f = Math.max(0, f);
int num = (int)f;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
*/
/*
//四角形
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
float posX = width * 3 / 4;
float posY = height * 2 / 3;
double f = Math.max(Math.abs(posX - i), Math.abs(posY - j));
f = Math.min(255, f / 6);
f = Math.max(0, f);
int num = (int)f;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
*/
/* 円亜種
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
double f = 0;
for(int k = 25; 1 <= k; k--){
if(Math.pow(Math.pow(posX - i, 2) + Math.pow(posY - j, 2), 0.5) < k * 100){
g2.setColor(new Color(k * 10, k * 10, k * 10));
}
}
g2.drawRect(i, j, 1, 1);
}
}
System.out.println(posX + ":" + posY + ":finish");
*/
/* タイル
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
int num = 0;
for(int i2 = 0; i2 < 24; i2++){
for(int j2 = 0; j2 < 24; j2++){
if((width * i2) / 24 <= i && i <= (width * (i2 + 1)) / 24 && height * j2 / 24 <= j && j <= (height * (j2 + 1)) / 24){
num = (23 - i2 + j2) * 5;
break;
}
}
}
//num = 255 - num;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
*/
/* タイル2
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
int num = 0;
for(int i2 = 0; i2 < 8; i2++){
for(int j2 = 0; j2 < 8; j2++){
if((width * i2) / 8 <= i && i <= (width * (i2 + 1)) / 8 && height * j2 / 8 <= j && j <= (height * (j2 + 1)) / 8){
int add = j2 % 2 == 0 ? i2 : 8 - i2;
num = j2 * 8 + add;
break;
}
}
}
num = num * 255 / 8 / 8;
num = 255 - num;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
ImageIO.write(bufferImage, "png", new File("タイル.png"));
*/
/*カーテン
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
float px = width / 2;
float py = height;
float f = Math.abs(2 * (i - px)) + Math.abs((j - py));
int num = (int)(f / 11);
num = 255 - num;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
*/
/* タイル渦巻
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
int num = 0;
for(int i2 = 0; i2 < 6; i2++){
for(int j2 = 0; j2 < 6; j2++){
if((width * i2) / 6 <= i && i <= (width * (i2 + 1)) / 6 && height * j2 / 6 <= j && j <= (height * (j2 + 1)) / 6){
int pow = 6;
int all = 0;
if(j2 == 0){
num = i2 * pow + all;
break;
}
all += 6 * pow;
if(i2 == 5){
num = j2 * pow + all;
break;
}
all += 5 * pow;
if(j2 == 5){
num = (5 - i2) * pow + all;
break;
}
all += 5 * pow;
if(i2 == 0){
num = (5 - j2) * pow + all;
break;
}
all += 4 * pow;
if(j2 == 1){
num = i2 * pow + all;
break;
}
all += 4 * pow;
if(i2 == 4){
num = j2 * pow + all;
break;
}
all += 3 * pow;
if(j2 == 4){
num = (5 - i2) * pow + all;
break;
}
all += 3 * pow;
if(i2 == 1){
num = (5 - j2) * pow + all;
break;
}
all += 2 * pow;
if(j2 == 2){
num = i2 * pow + all;
break;
}
all += 2 * pow;
if(i2 == 3){
num = j2 * pow + all;
break;
}
all += 1 * pow;
if(j2 == 3){
num = (5 - i2) * pow + all;
break;
}
}
}
}
num = 255 - num;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, height - 1 - j, 1, 1);
}
}
*/
/* 星
g2.drawImage(ImageIO.read(new File("back.png")), 0, 0, width, height, null);
Image image = ImageIO.read(new File("star.png"));
for(int i = 1; i < 150; i++){
g2.drawImage(image, 800 - i * 25, 450 - i * 25, i * 50, i * 50, null);
}
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
int c = 255 - new Color(bufferImage.getRGB(i, j)).getRed();
g2.setColor(new Color(c, c, c));
g2.fillRect(i, j, 1, 1);
}
}
ImageIO.write(bufferImage, "png", new File("星.png"));
*/
/* 円窓たくさん
for(int i = 0; i < 28; i++){
for(int j = 0; j < 16; j++){
for(int i2 = -30; i2 <= 30; i2++){
for(int j2 = -30; j2 <= 30; j2++){
int c = 255 - 2 * 42 + 2 * (int)Math.pow(i2 * i2 + j2 * j2, 0.5f);
//c = 255 - c;
g2.setColor(new Color(c, c, c));
g2.fillRect(60 * i + i2, 60 * j + j2, 1, 1);
}
}
}
}
for(int i = 0; i < 28; i++){
for(int j = 0; j < 16; j++){
for(int i2 = -30; i2 <= 20; i2++){
for(int j2 = -30; j2 <= 20; j2++){
if((int)Math.pow(i2 * i2 + j2 * j2, 0.5f) <= 20){
int c = i * 4 + j * 4 + (int)Math.pow(i2 * i2 + j2 * j2, 0.5f);
//c = 255 - c;
g2.setColor(new Color(c, c, c));
g2.fillRect(60 * i + i2, 60 * j + j2, 1, 1);
}
}
}
}
}
ImageIO.write(bufferImage, "png", new File("円窓たくさん.png"));
*/
/* 星2
g2.drawImage(ImageIO.read(new File("back.png")), 0, 0, width, height, null);
BufferedImage bufferImage3 =new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);//Buffer用イメージを作成
Graphics2D g3=bufferImage3.createGraphics();//描画用のGraphics2D型変数g2を取得
g3.setColor(new Color(255, 255, 255));
g3.fillRect(0, 0, width, height);
BufferedImage bufferImage4 =new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);//Buffer用イメージを作成
Graphics2D g4=bufferImage4.createGraphics();//描画用のGraphics2D型変数g2を取得
g4.setColor(new Color(255, 255, 255));
g4.fillRect(0, 0, width, height);
Image image = ImageIO.read(new File("star.png"));
for(int i = 1; i < 150; i++){
g3.drawImage(image, 533 - i * 25, 450 - i * 25, i * 50, i * 50, null);
}
for(int i = 1; i < 150; i++){
g4.drawImage(image, 1066 - i * 25, 450 - i * 25, i * 50, i * 50, null);
}
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
int c1 = new Color(bufferImage3.getRGB(i, j)).getRed();
int c2 = new Color(bufferImage4.getRGB(i, j)).getRed();
if (c2 <= c1) {
g2.setColor(new Color(c2, c2, c2));
} else {
g2.setColor(new Color(c1, c1, c1));
}
g2.drawRect(i, j, 1, 1);
}
}
ImageIO.write(bufferImage, "png", new File("星C.png"));
*/
/* ワイパー
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
double f = (Math.atan2(posX - i, posY - j) * 180d / Math.PI + 180) / 365 * 255;
f = Math.min(255, f);
f = Math.max(0, f);
int num = (int)f;
num = 255 - num;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
*/
/*
for(int i = 1; i <= 3; i++){
for(int j = 1; j <= 3; j++){
setGraphic(width * i / 4, height * j / 4, width, height, g2);
ImageIO.write(bufferImage, "png", new File("aaa" + i + j + ".png"));
}
System.out.println(i);
}
*/
//setGraphic(750, 320, width, height, g2);
//ImageIO.write(bufferImage, "png", new File("専用ワイプ.png"));
/*
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
float posX = 1230;
float posY = 580;
float f = (float)Math.pow(Math.pow(posX - i, 2) + Math.pow(posY - j, 2), 0.5f);
f = Math.min(255, f / 9.4f);
int num = 110 + (int)f;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
{
float distance = (i - 260) * (i - 260) + (j - 370) * (j - 370);
distance = (float)Math.pow(distance, 0.5f);
if(distance < 100){
int c = (int)(distance / 10);
g2.setColor(new Color(c, c, c));
g2.drawRect(i, j, 1, 1);
}
}
{
float distance = (i - 490) * (i - 490) + (j - 110) * (j - 110);
distance = (float)Math.pow(distance, 0.5f);
if(distance < 100){
int c = 10 + (int)(distance / 10);
g2.setColor(new Color(c, c, c));
g2.drawRect(i, j, 1, 1);
}
}
{
float distance = (i - 505) * (i - 505) + (j - 320) * (j - 320);
distance = (float)Math.pow(distance, 0.5f);
if(distance < 100){
int c = 20 + (int)(distance / 10);
g2.setColor(new Color(c, c, c));
g2.drawRect(i, j, 1, 1);
}
}
{
float distance = (i - 515) * (i - 515) + (j - 560) * (j - 560);
distance = (float)Math.pow(distance, 0.5f);
if(distance < 100){
int c = 30 + (int)(distance / 10);
g2.setColor(new Color(c, c, c));
g2.drawRect(i, j, 1, 1);
}
}
{
float distance = (i - 710) * (i - 710) + (j - 110) * (j - 110);
distance = (float)Math.pow(distance, 0.5f);
if(distance < 100){
int c = 40 + (int)(distance / 10);
g2.setColor(new Color(c, c, c));
g2.drawRect(i, j, 1, 1);
}
}
{
float distance = (i - 730) * (i - 730) + (j - 370) * (j - 370);
distance = (float)Math.pow(distance, 0.5f);
if(distance < 100){
int c = 50 + (int)(distance / 10);
g2.setColor(new Color(c, c, c));
g2.drawRect(i, j, 1, 1);
}
}
{
float distance = (i - 720) * (i - 720) + (j - 690) * (j - 690);
distance = (float)Math.pow(distance, 0.5f);
if(distance < 100){
int c = 60 + (int)(distance / 10);
g2.setColor(new Color(c, c, c));
g2.drawRect(i, j, 1, 1);
}
}
{
float distance = (i - 930) * (i - 930) + (j - 300) * (j - 300);
distance = (float)Math.pow(distance, 0.5f);
if(distance < 100){
int c = 70 + (int)(distance / 10);
g2.setColor(new Color(c, c, c));
g2.drawRect(i, j, 1, 1);
}
}
{
float distance = (i - 940) * (i - 940) + (j - 545) * (j - 545);
distance = (float)Math.pow(distance, 0.5f);
if(distance < 100){
int c = 80 + (int)(distance / 10);
g2.setColor(new Color(c, c, c));
g2.drawRect(i, j, 1, 1);
}
}
{
float distance = (i - 1090) * (i - 1090) + (j - 150) * (j - 150);
distance = (float)Math.pow(distance, 0.5f);
if(distance < 100){
int c = 90 + (int)(distance / 10);
g2.setColor(new Color(c, c, c));
g2.drawRect(i, j, 1, 1);
}
}
{
float distance = (i - 1090) * (i - 1090) + (j - 410) * (j - 410);
distance = (float)Math.pow(distance, 0.5f);
if(distance < 100){
int c = 100 + (int)(distance / 10);
g2.setColor(new Color(c, c, c));
g2.drawRect(i, j, 1, 1);
}
}
}
}
*/
ImageIO.write(bufferImage, "png", new File("専用円.png"));
/*
setGraphic(width * 1 / 11, height * 2 / 10, width, height, g2);
ImageIO.write(bufferImage, "png", new File("Circle10.png"));
setGraphic(width * 2 / 11, height * 2 / 10, width, height, g2);
ImageIO.write(bufferImage, "png", new File("Circle11.png"));
setGraphic(width * 3 / 11, height * 2 / 10, width, height, g2);
ImageIO.write(bufferImage, "png", new File("Circle12.png"));
setGraphic(width * 4 / 11, height * 2 / 10, width, height, g2);
ImageIO.write(bufferImage, "png", new File("Circle13.png"));
setGraphic(width * 5 / 11, height * 2 / 10, width, height, g2);
ImageIO.write(bufferImage, "png", new File("Circle14.png"));
setGraphic(width * 6 / 11, height * 2 / 10, width, height, g2);
ImageIO.write(bufferImage, "png", new File("Circle15.png"));
setGraphic(width * 7 / 11, height * 2 / 10, width, height, g2);
ImageIO.write(bufferImage, "png", new File("Circle16.png"));
setGraphic(width * 8 / 11, height * 2 / 10, width, height, g2);
ImageIO.write(bufferImage, "png", new File("Circle17.png"));
setGraphic(width * 9 / 11, height * 2 / 10, width, height, g2);
ImageIO.write(bufferImage, "png", new File("Circle18.png"));
setGraphic(width * 10 / 11, height * 2 / 10, width, height, g2);
ImageIO.write(bufferImage, "png", new File("Circle19.png"));
*/
g2.dispose();//不要になったグラフィクスは廃却
}
private static void setGraphic(float posX, float posY, int width, int height, Graphics2D g2) throws IOException {
/* 何か忘れた
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
float f;
if(j < posY + 300){
f = Math.abs(posX - i) + Math.abs(posY + 300 - j);
}
else{
f = Math.abs(posX - i) + 0 * Math.abs(posY + 300 - j);
}
f = Math.min(255, f / 7);
f = Math.max(0, f);
int num = (int)f;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
*/
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
/* ワイプ
{
double f = (Math.atan2(posX - i, j - posY) * 180d / Math.PI + 180) / 365 * 255;
if(f < 255 / 2){
f = 255 / 2 - f;
}
f = Math.min(255, f);
f = Math.max(0, f);
int num = (int)f;
num = 255 - num;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
*/
/* ねじれワイプ
{
double f = (Math.atan2(posX - i, j - posY) * 180d / Math.PI + 180) / 365 * 255;
if(f < 255 / 2){
f = 255 / 2 - f;
}
f = Math.min(255, f);
f = Math.max(0, f);
int num = (int)f;
num = 255 - num;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
*/
/* うずまき
g2.setColor(new Color(255, 255, 255));
g2.drawRect(i, j, 1, 1);
for(int k = -1; k < 20; k++){
double f = (Math.atan2(posX - i, posY - j) * 180d / Math.PI + 180) / 365 * 255;
if((150 * k + f * 150 / 255) * (150 * k + f * 150 / 255) < (posX - i) * (posX - i) + (posY - j) * (posY - j)) {
f = Math.min(255, (f / 20 + 255 * k / 20) * 2.5f);
f = Math.max(0, f);
int num = (int)f;
num = 255 - num;
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
*/
/* 一時停止円
float distance = (posX - i) * (posX - i) + (posY - j) * (posY - j);
distance = (float) Math.pow(distance, 0.5f);
if(distance <= 100) {
int c = (int)(distance / 11);
g2.setColor(new Color(c, c, c));
g2.drawRect(i, j, 1, 1);
} else {
int c = 100 + (int)(distance / 11);
g2.setColor(new Color(c, c, c));
g2.drawRect(i, j, 1, 1);
}
*/
}
}
/* 線をたくさん走らせる
for(int i = 0; i < width; i++){
g2.setColor(new Color(205 + 100 * Math.abs(i - width / 2) / width, 205 + 100 * Math.abs(i - width / 2) / width, 205 + 100 * Math.abs(i - width / 2) / width));
for(int j = 0; j < height; j++){
g2.drawLine(i, j, i, j);
}
}
for(int i = 51; i < 255; i++){
for(int j = 0; j < (i + 200) / 200; j++){
float pointX1 = (float)(Math.random() * width * 4);
pointX1 -= width * 2;
float pointY1 = (float)(Math.random() * height * 4);
pointY1 -= height * 2;
float pointX2 = (float)(Math.random() * width * 4);
pointX2 -= width * 2;
float pointY2 = (float)(Math.random() * height * 4);
pointY2 -= height * 2;
g2.setColor(new Color(255 - i, 255 - i, 255 - i));
g2.setStroke(new BasicStroke(50));
g2.drawLine((int)pointX1, (int)pointY1, (int)pointX2, (int)pointY2);
}
}
*/
/* 横ワイプからの縦ワイプ
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
int num = 170 + Math.abs(height / 2 - j) / 5;
g2.setColor(new Color(num, num, num));
g2.drawLine(i, j, i, j);
}
}
for(int i = 0; i < width; i++){
for(int j = height / 2 - 100; j < height / 2 + 101; j++){
int num = 80 * i / width;
g2.setColor(new Color(num, num, num));
g2.drawLine(i, j, i, j);
}
}
*/
/*
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
int num = 80 * j / height;
g2.setColor(new Color(num, num, num));
g2.drawLine(i, j, i, j);
}
}
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
if(width / 2 - 100 < i && i < width / 2 + 100){
continue;
}
float px = width / 2;
float py = height;
float f = Math.abs(2 * (i - px)) + Math.abs((j - py));
int num = (int)(f / 23 + 145);
g2.setColor(new Color(num, num, num));
g2.drawRect(i, j, 1, 1);
}
}
*/
}
}
using UnityEngine;
namespace SephirothTools.Core
{
/// <summary>
/// <para>
/// This is a class that generates grayscale images.
/// </para>
///
/// <para>
/// You can use it by setting "float setColor"
/// to an appropriate value for each pixel and executing it.
/// </para>
///
/// <para>
/// To execute it, run "Tools/SephirothSceneSwitchingEffects/
/// ExecSephirothGrayScaleGenerator" from the menu bar at the top of Unity.
/// </para>
/// </summary>
[UnityEditor.InitializeOnLoad]
public class SephirothGrayScaleImageGenerator
{
[UnityEditor.MenuItem("Tools/SephirothSceneSwitchingEffects/ExecSephirothGrayScaleGenerator")]
public static void Exec(){
Texture2D resultTexture2D = new(1920, 1080);
//Set each pixel here.(Edit by entering a value between 0 and 1 in "float setColor")
{
Vector2 centerPoint = new(resultTexture2D.width / 2, resultTexture2D.height / 2);
bool isFlipVertical = false;
bool isFlipHorizontal = false;
bool isBlackAndWhiteInversion = false;
for (int i = 0; i < resultTexture2D.width; i++)
{
for(int j = 0; j < resultTexture2D.height; j++)
{
float setColor = (Mathf.Atan2(i - centerPoint.x, j - centerPoint.y) + Mathf.PI) / Mathf.PI / 2;
/*float setColor = 0.5f - (Mathf.Atan2(i - centerPoint.x, j - centerPoint.y) + Mathf.PI) / Mathf.PI / 2 * 0.5f + 0.5f;
if(330 < (Mathf.Atan2(i - centerPoint.x, j - centerPoint.y) + Mathf.PI) * 180 / Mathf.PI)
{
setColor = Mathf.Pow(Mathf.Pow(i - centerPoint.x, 2) + Mathf.Pow(j - centerPoint.y, 2), 0.5f) / 1400;
}*/
/*float setColor = Mathf.Abs(((Mathf.Atan2(i - centerPoint.x, j - centerPoint.y) + Mathf.PI) * 360 / Mathf.PI) % 60 - 30) / 31 * 0.33f + 0.66f;
if(Mathf.Pow((centerPoint.x - i) * (centerPoint.x - i) + (centerPoint.y - j) * (centerPoint.y - j), 0.5f) < 600)
{
setColor = 0.33f - Mathf.Abs(((Mathf.Atan2(i - centerPoint.x, j - centerPoint.y) + Mathf.PI) * 360 / Mathf.PI) % 60 - 30) / 31 * 0.33f + 0.33f;
}
if (Mathf.Pow((centerPoint.x - i) * (centerPoint.x - i) + (centerPoint.y - j) * (centerPoint.y - j), 0.5f) < 300)
{
setColor = Mathf.Abs(((Mathf.Atan2(i - centerPoint.x, j - centerPoint.y) + Mathf.PI) * 360 / Mathf.PI) % 60 - 30) / 31 * 0.33f;
}*/
/*float disY = Mathf.Abs(j - centerPoint.y);
float setColor = (1f * i / resultTexture2D.width) * 0.33f + 0.66f;
if(disY + i / 15 < 400)
{
setColor = (1 - 1f * i / resultTexture2D.width) * 0.33f + 0.33f;
}
if(disY - i / 15 < 0)
{
setColor = (1f * i / resultTexture2D.width) * 0.33f;
}*/
/*float disX = Mathf.Abs(i - centerPoint.x);
float disY = Mathf.Abs(j - centerPoint.y);
float setColor = (disX * 2 + disY * 2 - 260) / (resultTexture2D.width + resultTexture2D.height - 260) * 0.4f + 0.6f;
if (disX < 130)
{
setColor = 0.4f - (1f * j / resultTexture2D.height) * 0.4f;
}
if (disY < 130)
{
setColor = (1f * i / resultTexture2D.width) * 0.4f;
}*/
/*float setColor = (Mathf.Atan2(i - centerPoint.x, j - centerPoint.y) + Mathf.PI) / Mathf.PI / 4 + 0.5f;
if(Mathf.Pow((i - centerPoint.x) * (i - centerPoint.x) + (j - centerPoint.y) * (j - centerPoint.y), 0.5f) < 400)
{
setColor = (Mathf.Atan2(i - centerPoint.x, j - centerPoint.y) + Mathf.PI) / Mathf.PI / 4;
}*/
//float setColor = ((Mathf.Atan2(i - centerPoint.x, j - centerPoint.y) + Mathf.PI) * 360 / Mathf.PI) % 30 / 30;
//float setColor = 1 - Mathf.Abs(((Mathf.Atan2(i - centerPoint.x, j - centerPoint.y) + Mathf.PI) * 360 / Mathf.PI) % 30 / 15 - 1);
//float setColor = Mathf.Pow((i - centerPoint.x) * (i - centerPoint.x) + (j - centerPoint.y) * (j - centerPoint.y), 0.5f) / 7 / 255;
//float setColor = (Mathf.Atan2(i - centerPoint.x, j - centerPoint.y) + Mathf.PI) / Mathf.PI / 2;
if (setColor < 0)
{
throw new System.Exception("setColor is " + setColor);
}
if (1 < setColor)
{
throw new System.Exception("setColor is " + setColor);
}
resultTexture2D.SetPixel(i, j, new Color(setColor, setColor, setColor));
}
}
if (isFlipVertical)
{
float[,] backUpArray = new float[resultTexture2D.width, resultTexture2D.height];
for (int i = 0; i < resultTexture2D.width; i++)
{
for (int j = 0; j < resultTexture2D.height; j++)
{
backUpArray[i, j] = resultTexture2D.GetPixel(i, j).r;
}
}
for (int i = 0; i < resultTexture2D.width; i++)
{
for (int j = 0; j < resultTexture2D.height; j++)
{
float setValue = backUpArray[resultTexture2D.width - i - 1, j];
Color resultColor = new Color(setValue, setValue, setValue);
resultTexture2D.SetPixel(i, j, resultColor);
}
}
}
if (isFlipHorizontal)
{
float[,] backUpArray = new float[resultTexture2D.width, resultTexture2D.height];
for (int i = 0; i < resultTexture2D.width; i++)
{
for (int j = 0; j < resultTexture2D.height; j++)
{
backUpArray[i, j] = resultTexture2D.GetPixel(i, j).r;
}
}
for (int i = 0; i < resultTexture2D.width; i++)
{
for (int j = 0; j < resultTexture2D.height; j++)
{
float setValue = backUpArray[i, resultTexture2D.height - j - 1];
Color resultColor = new Color(setValue, setValue, setValue);
resultTexture2D.SetPixel(i, j, resultColor);
}
}
}
if (isBlackAndWhiteInversion)
{
for (int i = 0; i < resultTexture2D.width; i++)
{
for (int j = 0; j < resultTexture2D.height; j++)
{
float setValue = 1f - resultTexture2D.GetPixel(i, j).r;
Color resultColor = new Color(setValue, setValue, setValue);
resultTexture2D.SetPixel(i, j, resultColor);
}
}
}
}
//Set fileName here.
string fileName = "sample1.png";
System.IO.File.WriteAllBytes(SephirothRootFolder.GetMyPath() + "SephirothSceneSwitchingEffects/RecommendedImages/Generator/" + fileName, resultTexture2D.EncodeToPNG());
UnityEditor.AssetDatabase.Refresh();
Debug.Log("Generation completed. " + SephirothRootFolder.GetMyPath() + "SephirothSceneSwitchingEffects/RecommendedImages/Generator/" + fileName);
}
}
}
上記の例では
円が広がると言ったエフェクトを
作成しています。
以上動画編集で使う事が出来る
エフェクトをプログラミングで作成する
試みについて紹介しました。
動画編集で使う事が出来る
グレースケール画像は便利な割に
ネット上にあまり落ちていません。
「ルール画像」で検索すると
別の作者さんの作品が 1 件
ヒットする程度です。
私はそれしか見つける事が
出来ませんでした。
グレースケール画像は
プログラミングで簡単に作成出来ますので
是非皆さんも作って
公開してみてはいかがでしょうか?
皆さんがこの記事を
動画編集作業に活躍出来たならば
非常に嬉しいです。
閲覧ありがとうございました。