Fix graphics recognition algorithms and added a test suite.

secondmonitor
sigonasr2 4 years ago
parent a6958f1669
commit 289cb13833
  1. 2
      DivaBot/colorData
  2. 91
      DivaBot/src/MyRobot.java
  3. 76
      DivaBot/src/TypeFace.java
  4. 39
      DivaBot/src/sig/utils/ImageUtils.java
  5. BIN
      DivaBot/testsuite/shake it!_EXplay_568_88_8_4_7_96.03.png
  6. BIN
      DivaBot/testsuite/え?あぁ、そう。_EXEXplay_499_121_11_9_43_77.11.png
  7. BIN
      DivaBot/testsuite/どういうことなの!?_EXplay_449_85_3_0_3_95.01.png
  8. BIN
      DivaBot/testsuite/サマーアイドル_EXplay_959_56_19_5_10_81.32.png
  9. BIN
      DivaBot/testsuite/テレカクシ思春期_EXplay_44_108_7_4_18_81.8.png
  10. BIN
      DivaBot/testsuite/天樂_EXplay_361_58_9_4_11_92.67.png
  11. BIN
      DivaBot/testsuite/番凩_EXEXplay_41_110_1_10_21_77.76.png
  12. BIN
      DivaBot/testsuite/結ンデ開イテ羅刹ト骸_EXEXplay_47_123_10_5_46_74.19.png
  13. BIN
      DivaBot/typeface1.png
  14. BIN
      DivaBot/typeface2.png

File diff suppressed because one or more lines are too long

@ -1,8 +1,12 @@
import java.awt.Color;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
@ -13,6 +17,7 @@ import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.List;
import java.util.Timer;
@ -31,14 +36,14 @@ import javax.swing.JTextField;
import javax.swing.KeyStroke;
import sig.utils.FileUtils;
import sig.utils.ImageUtils;
import sig.utils.SoundUtils;
public class MyRobot{
Robot MYROBOT;
Color SCREEN[][];
static SongData SONGS[];
static String SONGNAMES[] = new String[] {"Yellow","The secret garden","Tell Your World","愛言葉","Weekender Girl","歌に形はないけれど","えれくとりっく・えんじぇぅ","神曲","カンタレラ","巨大少女","クローバー♣クラブ","恋スルVOC@LOID","桜ノ雨 ","39","深海シティアンダーグラウンド","深海少女","積乱雲グラフィティ","千年の独奏歌","ダブルラリアット","ハジメテノオト","初めての恋が終わる時","Packaged","Palette","Freely Tomorrow","from Y to Y","みくみくにしてあげる♪","メルト","モノクロ∞ブルースカイ","ゆめゆめ","1/6 -out of the gravity-","ACUTE","インタビュア","LOL -lots of laugh-","Glory 3usi9","soundless voice","ジェミニ","白い雪のプリンセスは","スキキライ","タイムマシン","Dear","DECORATOR","トリコロール・エア・ライン","Nostalgic","Hand in Hand","Fire◎Flower","ブラック★ロックシューター","メテオ","ワールドイズマイン","アマツキツネ","erase or zero","エレクトロサチュレイタ","on the rocks","からくりピエロ","カラフル×メロディ","Catch the Wave","キャットフード","サマーアイドル","shake it!","Just Be Friends","スイートマジック","SPiCa -39's Giving Day Edition-","番凩","テレカクシ思春期","天樂","どういうことなの!?","東京テディベア","どりーみんチュチュ","トリノコシティ","ネトゲ廃人シュプレヒコール","No Logic","ハイハハイニ","はじめまして地球人さん","*ハロー、プラネット。","Hello, Worker","忘却心中","magnet","右肩の蝶","結ンデ開イテ羅刹ト骸","メランコリック","リモコン","ルカルカ★ナイトフィーバー","炉心融解","WORLD'S END UMBRELLA","アカツキアライヴァル","アゲアゲアゲイン","1925","え?あぁ、そう。","エイリアンエイリアン","ODDS&ENDS","君の体温","こっち向いて Baby","壊セ壊セ","39みゅーじっく!","サンドリヨン","SING&SMILE","スノーマン","DYE","なりすましゲンガー","ヒバナ","ヒビカセ","ブラックゴールド","ミラクルペイント","指切り","ありふれたせかいせいふく","アンハッピーリフレイン","大江戸ジュリアナイト","ゴーストルール","こちら、幸福安心委員会です。","孤独の果て -extend edition-","ジターバグ","Sweet Devil","砂の惑星","テオ","初音ミクの消失","秘密警察","妄想スケッチ","リンちゃんなう!","ローリンガール","ロキ","ロミオとシンデレラ","エンヴィキャットウォーク","骸骨楽団とリリア","サイハテ","ジグソーパズル","千本桜","ピアノ×フォルテ×スキャンダル","Blackjack","ぽっぴっぽー","裏表ラバーズ","Sadistic.Music∞Factory","デンパラダイム","二次元ドリームフィーバー","ネガポジ*コンティニューズ","初音ミクの激唱","ワールズエンド・ダンスホール","ココロ","システマティック・ラヴ","Knife","二息歩行","PIANO*GIRL","夢喰い白黒バク"};
static String SONGNAMES[] = new String[] {"Yellow","The secret garden","Tell Your World","愛言葉","Weekender Girl","歌に形はないけれど","えれくとりっく・えんじぇぅ","神曲","カンタレラ","巨大少女","クローバー♣クラブ","恋スルVOC@LOID","桜ノ雨 ","39","深海シティアンダーグラウンド","深海少女","積乱雲グラフィティ","千年の独奏歌","ダブルラリアット","ハジメテノオト","初めての恋が終わる時","Packaged","Palette","Freely Tomorrow","from Y to Y","みくみくにしてあげる♪","メルト","モノクロ∞ブルースカイ","ゆめゆめ","1/6 -out of the gravity-","ACUTE","インタビュア","LOL -lots of laugh-","Glory 3usi9","soundless voice","ジェミニ","白い雪のプリンセスは","スキキライ","タイムマシン","Dear","DECORATOR","トリコロール・エア・ライン","Nostalgic","Hand in Hand","Fire◎Flower","ブラック★ロックシューター","メテオ","ワールドイズマイン","アマツキツネ","erase or zero","エレクトロサチュレイタ","on the rocks","からくりピエロ","カラフル×メロディ","Catch the Wave","キャットフード","サマーアイドル","shake it!","Just Be Friends","スイートマジック","SPiCa -39's Giving Day Edition-","番凩","テレカクシ思春期","天樂","どういうことなの!?","東京テディベア","どりーみんチュチュ","トリノコシティ","ネトゲ廃人シュプレヒコール","No Logic","ハイハハイニ","はじめまして地球人さん","*ハロー、プラネット。","Hello, Worker","忘却心中","magnet","右肩の蝶","結ンデ開イテ羅刹ト骸","メランコリック","リモコン","ルカルカ★ナイトフィーバー","炉心融解","WORLD'S END UMBRELLA","アカツキアライヴァル","アゲアゲアゲイン","1925","え?あぁ、そう。","エイリアンエイリアン","ODDS&ENDS","君の体温","こっち向いて Baby","壊セ壊セ","39みゅーじっく!","サンドリヨン","SING&SMILE","スノーマン","DYE","なりすましゲンガー","ヒバナ","ヒビカセ","ブラックゴールド","ミラクルペイント","指切り","ありふれたせかいせいふく","アンハッピーリフレイン","大江戸ジュリアナイト","ゴーストルール","こちら、幸福安心委員会です。","孤独の果て -extend edition-","ジターバグ","Sweet Devil","砂の惑星","テオ","初音ミクの消失","秘密警察","妄想スケッチ","リンちゃんなう!","ローリンガール","ロキ","ロミオとシンデレラ","エンヴィキャットウォーク","骸骨楽団とリリア","サイハテ","ジグソーパズル","千本桜","ピアノ×フォルテ×スキャンダル","Blackjack","ぽっぴっぽー","裏表ラバーズ","Sadistic.Music∞Factory","デンパラダイム","二次元ドリームフィーバー","ネガポジ*コンティニューズ","初音ミクの激唱","ワールズエンド・ダンスホール","ココロ","システマティック・ラヴ","Knife","二息歩行","PIANOGIRL","夢喰い白黒バク"};
int SCREEN_X;
int SCREEN_Y;
int WINDOW_X;
@ -107,7 +112,6 @@ public class MyRobot{
if (OnResultsScreen() && !recordedResults && !recordingResults && results.size()==0) {
lastSongSelectTime=System.currentTimeMillis();
//1885,761
if (eyeTrackingSceneOn) {
eyeTrackingSceneOn=false;
gotoxy(800,64);
@ -115,6 +119,7 @@ public class MyRobot{
gotoxy(1870,761);
click();
}
//1885,761
//System.out.println(typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,451,115,26))));
//System.out.println(typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,484,115,26))));
//System.out.println(typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,518,115,26))));
@ -141,7 +146,7 @@ public class MyRobot{
if (cool==-1 || fine==-1 || safe==-1 || sad==-1 || worst==-1 || percent==-0.01f) {
System.out.println("Waiting for results to populate...");
} else
if (cool!=lastcool || lastfine!=fine || lastsafe!=safe || lastsad!=sad || lastworst!=worst || lastpercent!=percent){
if (cool!=lastcool || lastfine!=fine || lastsafe!=safe || lastsad!=sad || lastworst!=worst /*|| lastpercent!=percent*/){
System.out.println("Results for "+selectedSong.title+" "+difficulty+": "+cool+"/"+fine+"/"+safe+"/"+sad+"/"+worst+" "+percent+"%");
File songFolder = new File(selectedSong.title+"/"+difficulty);
if (!songFolder.exists()) {
@ -187,17 +192,25 @@ public class MyRobot{
MYROBOT.keyPress(KeyEvent.VK_ALT);
MYROBOT.keyPress(KeyEvent.VK_TAB);
MYROBOT.keyRelease(KeyEvent.VK_ALT);
MYROBOT.setAutoDelay(250);
MYROBOT.setAutoDelay(5000);
MYROBOT.keyRelease(KeyEvent.VK_TAB);
sleep(2000);
boolean first=true;
for (Result r : results) {
if (!first) {
sleep(5000);
MYROBOT.setAutoDelay(5000);
} else {
first=false;
MYROBOT.setAutoDelay(100);
TYPE_DELAY=50;
}
type(r.songName);
StringSelection selection = new StringSelection((r.songName.equalsIgnoreCase("PIANOGIRL"))?"PIANO*GIRL":r.songName);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(selection, selection);
MYROBOT.keyPress(KeyEvent.VK_CONTROL);
MYROBOT.keyPress(KeyEvent.VK_V);
MYROBOT.keyRelease(KeyEvent.VK_V);
MYROBOT.keyRelease(KeyEvent.VK_CONTROL);
MYROBOT.setAutoDelay(100);
MYROBOT.keyPress(KeyEvent.VK_TAB);
type(Integer.toString(r.cool));
MYROBOT.keyPress(KeyEvent.VK_TAB);
@ -234,13 +247,12 @@ public class MyRobot{
MYROBOT.keyRelease(KeyEvent.VK_TAB);
recordingResults=false;
}
}
} else {
if (!OnResultsScreen() && recordedResults) {
recordedResults=false;
}
}
}
}
//572,453
//Red: 100-200, Blue: 200-255 Purple (EXEX)
//Red: 150-255, Green: < 50 Blue: < 50 (EX)
@ -413,9 +425,68 @@ public class MyRobot{
//p.getGraphics().drawImage(MYROBOT.createScreenCapture(new Rectangle(1205,553,160,26)), 0, i+=26, f);
//p.getGraphics().drawImage(MYROBOT.createScreenCapture(new Rectangle(1205,583,160,26)), 0, i+=26, f);
//p.getGraphics().drawImage(MYROBOT.createScreenCapture(new Rectangle(1428,361,128,30)), 0, i+=26, f);
RunTests();
BotMain();
}
void RunTests() {
//418,204
/*int cool = typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,451,115,26)),new File(tmp,"cool"));
int fine = typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,484,115,26)),new File(tmp,"fine"));
int safe = typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,518,115,26)),new File(tmp,"safe"));
int sad = typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,553,115,26)),new File(tmp,"sad"));
int worst = typeface1.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1235,583,115,26)),new File(tmp,"worst"));
float percent = (float)typeface2.extractNumbersFromImage(MYROBOT.createScreenCapture(new Rectangle(1428,361,128,30)),new File(tmp,"percent"))/100f;*/
selectedSong=new SongData("test",new Color[] {});
difficulty="EXEX";
RunTest("shake it!_EXplay_568_88_8_4_7_96.03.png",580,80,0,4,7,95.03f);
RunTest("え?あぁ、そう。_EXEXplay_499_121_11_9_43_77.11.png",439,121,11,5,43,77.11f);
RunTest("サマーアイドル_EXplay_959_56_19_5_10_81.32.png",363,58,15,5,10,84.32f);
RunTest("テレカクシ思春期_EXplay_44_108_7_4_18_81.8.png",447,109,7,4,16,84.80f);
RunTest("どういうことなの!?_EXplay_449_85_3_0_3_95.01.png",448,85,2,0,3,95.01f);
RunTest("天樂_EXplay_361_58_9_4_11_92.67.png",351,56,8,4,11,92.67f);
RunTest("番凩_EXEXplay_41_110_1_10_21_77.76.png",431,110,17,10,31,77.79f);
RunTest("結ンデ開イテ羅刹ト骸_EXEXplay_47_123_10_5_46_74.19.png",471,123,10,5,46,74.19f);
}
void RunTest(String _img,int _cool,int _fine, int _safe, int _sad, int _worst, float _percent) {
System.out.println("Running test "+_img);
long startTime = System.currentTimeMillis();
String testdir="testsuite";
Point offset = new Point(418,204);
File tmp = new File("tmp");
if (tmp.exists()) {
FileUtils.deleteFile(tmp);
} else {
tmp.mkdir();
}
BufferedImage img=null;
try {
img = ImageIO.read(new File(testdir,_img));
} catch (IOException e) {
e.printStackTrace();
}
int cool = typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(1235-offset.x,451-offset.y,115,26)),new File(tmp,"cool"));
int fine = typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(1235-offset.x,484-offset.y,115,26)),new File(tmp,"fine"));
int safe = typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(1235-offset.x,518-offset.y,115,26)),new File(tmp,"safe"));
int sad = typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(1235-offset.x,553-offset.y,115,26)),new File(tmp,"sad"));
int worst = typeface1.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(1235-offset.x,583-offset.y,115,26)),new File(tmp,"worst"));
float percent = (float)typeface2.extractNumbersFromImage(ImageUtils.cropImage(img,new Rectangle(1428-offset.x,361-offset.y,128,30)),new File(tmp,"percent"))/100f;
assert cool == _cool : "Expected cool count to be "+_cool+", got "+cool;
assert fine == _fine : "Expected fine count to be "+_fine+", got "+fine;
assert safe == _safe : "Expected safe count to be "+_safe+", got "+safe;
assert sad == _sad : "Expected sad count to be "+_sad+", got "+sad;
assert worst == _worst : "Expected worst count to be "+_worst+", got "+worst;
assert percent == _percent : "Expected percent to be "+_percent+", got "+percent;
System.out.println(" Passed ("+(System.currentTimeMillis()-startTime)+"ms)!");
}
boolean isOnSongSelect() {
Color c = new Color(MYROBOT.createScreenCapture(new Rectangle(1255,824,20,20)).getRGB(10, 10));
return c.getRed()==43 && c.getGreen()==88 && c.getBlue()==213;

@ -12,6 +12,7 @@ import java.util.List;
import javax.imageio.ImageIO;
import sig.utils.FileUtils;
import sig.utils.ImageUtils;
public class TypeFace {
@ -23,7 +24,13 @@ public class TypeFace {
int red_minthreshold = 0;
int blue_maxthreshold = 255;
int green_maxthreshold = 150;
int red_maxthreshold = 100;
int red_maxthreshold = 126;
int blue_fillminthreshold = 75;
int green_fillminthreshold = 0;
int red_fillminthreshold = 0;
int blue_fillmaxthreshold = 255;
int green_fillmaxthreshold = 150;
int red_fillmaxthreshold = 100;
boolean darkFillCheck = true;
Color[][] numbers = new Color[WIDTH*HEIGHT][NUMBER_COUNT];
BufferedImage baseImg;
@ -55,6 +62,7 @@ public class TypeFace {
final boolean DEBUG_IMG = false;
int iterations=0;
while (X<img.getWidth()) {
boolean success=true;
Color p = new Color(img.getRGB(X, midY),true);
@ -66,14 +74,6 @@ public class TypeFace {
p.getRed()>red_minthreshold && p.getRed()<red_maxthreshold) {
//We found a dark pixel.
state=1;
if (darkFillCheck) {
success = fillDark(img,X,midY,0,0);
if (!success) {
//We're done.
X=img.getWidth();
break;
}
}
if (DEBUG_IMG) {
try {
BufferedImage img2 = ImageUtils.copyBufferedImage(img);
@ -83,6 +83,14 @@ public class TypeFace {
e.printStackTrace();
}
}
if (darkFillCheck) {
success = fillDark(img,X,midY,0,0);
if (!success) {
//We're done.
X=img.getWidth();
break;
}
}
}
}break;
case 1:{
@ -126,39 +134,45 @@ public class TypeFace {
}break;
case 3:{
//Figure out which number in the typeface it best represents.
if (numberImg.getHeight()>numberImg.getWidth()) {
numberImg = ImageUtils.toBufferedImage(numberImg.getScaledInstance(-1, HEIGHT, Image.SCALE_FAST));
} else {
numberImg = ImageUtils.toBufferedImage(numberImg.getScaledInstance(WIDTH, -1, Image.SCALE_FAST));
}
numberImg = ImageUtils.toBufferedImage(numberImg.getScaledInstance(WIDTH, HEIGHT, Image.SCALE_FAST));
//System.out.println(numberImg.getWidth()+"x"+numberImg.getHeight());
int[] hits = new int[NUMBER_COUNT];
double highestRatio = 0;
int highest = 0;
for (int k=0;k<NUMBER_COUNT;k++) {
BufferedImage img2 = ImageUtils.copyBufferedImage(numberImg);
for (int i=0;i<WIDTH;i++) {
for (int j=0;j<HEIGHT;j++) {
if (i<numberImg.getWidth() &&
j<numberImg.getHeight()) {
Color pixel = new Color(numberImg.getRGB(i, j));
if (numbers[i*HEIGHT+j][k].getRed()==pixel.getRed() && numbers[i*HEIGHT+j][k].getRed()==pixel.getGreen() && numbers[i*HEIGHT+j][k].getBlue()==pixel.getBlue()) {
if (numbers[i*HEIGHT+j][k].getRed()==pixel.getRed() && numbers[i*HEIGHT+j][k].getGreen()==pixel.getGreen() && numbers[i*HEIGHT+j][k].getBlue()==pixel.getBlue()) {
hits[k]++;
//System.out.println("Hit for "+((k+1)%NUMBER_COUNT)+"! "+hits[k] + "/"+numbers[i*HEIGHT+j][k]+"/"+pixel);
if ((double)hits[k]/(WIDTH*HEIGHT)>highestRatio) {
highestRatio = (double)(hits[k])/(WIDTH*HEIGHT);
highestRatio= (double)(hits[k])/(WIDTH*HEIGHT);
highest=k;
}
} else {
if (pixel.equals(Color.WHITE)) {
img2.setRGB(i, j, Color.BLUE.getRGB());
} else {
img2.setRGB(i, j, Color.RED.getRGB());
}
//FileUtils.logToFile("Pixel difference: "+numbers[i*HEIGHT+j][k]+"/"+pixel, new File(saveLoc,(iterations)+".txt").getPath());
}
}
}
}
FileUtils.logToFile(((k+1)%NUMBER_COUNT)+":"+((double)(hits[k])/(WIDTH*HEIGHT)), new File(saveLoc,(iterations)+".txt").getPath());
try {
ImageIO.write(numberImg,"png",new File(saveLoc,((highest+1)%NUMBER_COUNT)+".png"));
ImageIO.write(img2,"png",new File(saveLoc,(iterations)+"_"+((k+1)%NUMBER_COUNT)+".png"));
} catch (IOException e) {
e.printStackTrace();
}
}
//System.out.println("Matches closest to "+((highest+1)%NUMBER_COUNT)+" with "+highestRatio);
iterations++;
extractedNumbers+=Integer.toString((highest+1)%NUMBER_COUNT);
state=4;
}break;
@ -197,9 +211,9 @@ public class TypeFace {
Color p = null;
if (startX+x+1<img.getWidth()) {
p = new Color(img.getRGB(startX+x+1, startY+y));
if (p.getBlue()>blue_minthreshold && p.getBlue()<blue_maxthreshold &&
p.getGreen()>green_minthreshold && p.getGreen()<green_maxthreshold &&
p.getRed()>red_minthreshold && p.getRed()<red_maxthreshold) {
if (p.getBlue()>blue_fillminthreshold && p.getBlue()<blue_fillmaxthreshold &&
p.getGreen()>green_fillminthreshold && p.getGreen()<green_fillmaxthreshold &&
p.getRed()>red_fillminthreshold && p.getRed()<red_fillmaxthreshold) {
fillDark(img,startX,startY,x+1,y);
}
} else {
@ -207,9 +221,9 @@ public class TypeFace {
}
if (startX+x-1>0) {
p = new Color(img.getRGB(startX+x-1, startY+y));
if (p.getBlue()>blue_minthreshold && p.getBlue()<blue_maxthreshold &&
p.getGreen()>green_minthreshold && p.getGreen()<green_maxthreshold &&
p.getRed()>red_minthreshold && p.getRed()<red_maxthreshold) {
if (p.getBlue()>blue_fillminthreshold && p.getBlue()<blue_fillmaxthreshold &&
p.getGreen()>green_fillminthreshold && p.getGreen()<green_fillmaxthreshold &&
p.getRed()>red_fillminthreshold && p.getRed()<red_fillmaxthreshold) {
fillDark(img,startX,startY,x-1,y);
}
} else {
@ -217,9 +231,9 @@ public class TypeFace {
}
if (startY+y+1<img.getHeight()) {
p = new Color(img.getRGB(startX+x, startY+y+1));
if (p.getBlue()>blue_minthreshold && p.getBlue()<blue_maxthreshold &&
p.getGreen()>green_minthreshold && p.getGreen()<green_maxthreshold &&
p.getRed()>red_minthreshold && p.getRed()<red_maxthreshold) {
if (p.getBlue()>blue_fillminthreshold && p.getBlue()<blue_fillmaxthreshold &&
p.getGreen()>green_fillminthreshold && p.getGreen()<green_fillmaxthreshold &&
p.getRed()>red_fillminthreshold && p.getRed()<red_fillmaxthreshold) {
fillDark(img,startX,startY,x,y+1);
}
} else {
@ -227,9 +241,9 @@ public class TypeFace {
}
if (startY+y-1>0) {
p = new Color(img.getRGB(startX+x, startY+y-1));
if (p.getBlue()>blue_minthreshold && p.getBlue()<blue_maxthreshold &&
p.getGreen()>green_minthreshold && p.getGreen()<green_maxthreshold &&
p.getRed()>red_minthreshold && p.getRed()<red_maxthreshold) {
if (p.getBlue()>blue_fillminthreshold && p.getBlue()<blue_fillmaxthreshold &&
p.getGreen()>green_fillminthreshold && p.getGreen()<green_fillmaxthreshold &&
p.getRed()>red_fillminthreshold && p.getRed()<red_fillmaxthreshold) {
fillDark(img,startX,startY,x,y-1);
}
} else {
@ -301,7 +315,7 @@ public class TypeFace {
int offsetX = 0;
int finalHeight = maxY-minY+1;
int offsetY = 0;
if (finalWidth > finalHeight) {
/*if (finalWidth > finalHeight) {
//Add padding for height.
offsetY += (finalWidth-finalHeight)/2;
finalHeight+= offsetY*2;
@ -310,7 +324,7 @@ public class TypeFace {
//Add padding for width.
offsetX += (finalHeight-finalWidth)/2;
finalWidth+= offsetX*2;
}
}*/
BufferedImage bufferedImage = new BufferedImage(finalWidth, finalHeight,
BufferedImage.TYPE_INT_RGB);

@ -2,6 +2,7 @@ package sig.utils;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
public class ImageUtils {
@ -39,6 +40,44 @@ public class ImageUtils {
bGr.drawImage(img, 0, 0, null);
bGr.dispose();
// Return the buffered image
return bimage;
}
public static BufferedImage cropImage(BufferedImage img,Rectangle offset)
{
// Create a buffered image with transparency
BufferedImage bimage = new BufferedImage(offset.width, offset.height, BufferedImage.TYPE_INT_ARGB);
// Draw the image on to the buffered image
Graphics2D bGr = bimage.createGraphics();
bGr.drawImage(img, -offset.x, -offset.y, null);
bGr.dispose();
// Return the buffered image
return bimage;
}
public static BufferedImage copyBufferedImages(BufferedImage...img)
{
int widthSum=0;
int maxHeight=0;
for (int i=0;i<img.length;i++) {
widthSum+=img[i].getWidth();
maxHeight=Math.max(maxHeight, img[i].getHeight());
}
// Create a buffered image with transparency
BufferedImage bimage = new BufferedImage(widthSum, maxHeight, BufferedImage.TYPE_INT_ARGB);
// Draw the image on to the buffered image
Graphics2D bGr = bimage.createGraphics();
int X=0;
for (int i=0;i<img.length;i++) {
bGr.drawImage(img[i], X, 0, null);
X+=img[i].getWidth();
}
bGr.dispose();
// Return the buffered image
return bimage;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Loading…
Cancel
Save