parent
ab423e29b6
commit
22d7efb968
@ -1,93 +1,58 @@ |
||||
package me.lensferno.dogename.controllers; |
||||
|
||||
import com.jfoenix.controls.JFXSpinner; |
||||
import javafx.application.Platform; |
||||
import javafx.event.ActionEvent; |
||||
import javafx.fxml.FXML; |
||||
import javafx.scene.control.TextArea; |
||||
import javafx.scene.text.Text; |
||||
import javafx.stage.Stage; |
||||
import me.lensferno.dogename.ocr.Ocr; |
||||
import me.lensferno.dogename.ocr.ScreenCapture; |
||||
import me.lensferno.dogename.utils.ocr.ScreenCapture; |
||||
import me.lensferno.dogename.utils.Clipboard; |
||||
|
||||
public class OcrPaneController { |
||||
|
||||
Ocr ocr; |
||||
|
||||
@FXML |
||||
private TextArea ocrText; |
||||
|
||||
@FXML |
||||
private Text statusText; |
||||
|
||||
@FXML |
||||
private JFXSpinner loadingSpinner; |
||||
|
||||
Stage pStage; |
||||
Stage mainStage; |
||||
|
||||
public void setpStage(Stage pStage) { |
||||
this.pStage = pStage; |
||||
public void setMainStage(Stage mainStage) { |
||||
this.mainStage = mainStage; |
||||
} |
||||
|
||||
@FXML |
||||
void addNew(ActionEvent event) { |
||||
void addNew() { |
||||
|
||||
Stage stage=(Stage)ocrText.getScene().getWindow(); |
||||
stage.hide(); |
||||
pStage.hide(); |
||||
Stage thisStage=(Stage)ocrText.getScene().getWindow(); |
||||
thisStage.hide(); |
||||
mainStage.hide(); |
||||
|
||||
//等待系统动画结束
|
||||
// 等待系统动画结束
|
||||
try { |
||||
Thread.sleep(500); |
||||
} catch (InterruptedException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
|
||||
boolean captureSuccess= ScreenCapture.getScreenCapture(); |
||||
|
||||
if(!captureSuccess){ |
||||
statusText.setText("状态:截屏失败。"); |
||||
System.out.println("状态:截屏失败。"); |
||||
pStage.show(); |
||||
stage.show(); |
||||
return; |
||||
} |
||||
loadingSpinner.setVisible(true); |
||||
|
||||
if(ocr==null){ |
||||
ocr=new Ocr(); |
||||
ocr.init(); |
||||
} |
||||
|
||||
new Thread(()->{ |
||||
boolean ocrSuccrss=ocr.identifyPrecisely(ScreenCapture.SCREEN_CAPTURE_LOCA); |
||||
|
||||
if (ocrSuccrss) { |
||||
ScreenCapture screenCapture = new ScreenCapture(); |
||||
|
||||
Platform.runLater(()->{ |
||||
ocrText.setText(ocrText.getText()+ocr.getResult()); |
||||
statusText.setText("状态:成功。"); |
||||
System.out.println("状态:成功。"); |
||||
loadingSpinner.setVisible(false); |
||||
ocrText.textProperty().bindBidirectional(screenCapture.resultProperty()); |
||||
loadingSpinner.visibleProperty().bind(screenCapture.endProperty().not()); |
||||
|
||||
}); |
||||
}else { |
||||
Platform.runLater(()->{ |
||||
ocrText.setText(ocr.getResult()); |
||||
statusText.setText("状态:失败。"); |
||||
System.out.println("状态:失败。"); |
||||
loadingSpinner.setVisible(false); |
||||
screenCapture.startCapture(); |
||||
|
||||
}); |
||||
screenCapture.endProperty().addListener((observable, oldValue, end) -> { |
||||
if (end) { |
||||
mainStage.show(); |
||||
thisStage.show(); |
||||
} |
||||
}).start(); |
||||
pStage.show(); |
||||
stage.show(); |
||||
}); |
||||
} |
||||
|
||||
@FXML |
||||
void copyText(ActionEvent event) { |
||||
void copyText() { |
||||
Clipboard.copyToClipboard(ocrText.getText()); |
||||
} |
||||
} |
||||
|
@ -1,205 +0,0 @@ |
||||
package me.lensferno.dogename.ocr; |
||||
|
||||
import java.io.*; |
||||
import javax.swing.*; |
||||
import java.awt.*; |
||||
import java.awt.event.*; |
||||
import java.awt.image.*; |
||||
import javax.imageio.*; |
||||
|
||||
//edited code from https://blog.csdn.net/caoyuan10036/article/details/7199505
|
||||
|
||||
public class ScreenCapture { |
||||
// test main
|
||||
/* |
||||
public static void main(String[] args) { |
||||
File tempFile = new File( "files"+File.separator+"ocr.png"); |
||||
ScreenCapture capture = ScreenCapture.getInstance(); |
||||
capture.captureImage(); |
||||
JLabel imagebox = new JLabel(); |
||||
imagebox.setIcon(capture.getPickedIcon()); |
||||
try { |
||||
capture.saveToFile(tempFile); |
||||
System.out.println("Over"); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
|
||||
} |
||||
*/ |
||||
|
||||
public static final String SCREEN_CAPTURE_LOCA="files"+File.separator+"ocrCache.png"; |
||||
|
||||
private static boolean canceled =false; |
||||
|
||||
|
||||
public static boolean getScreenCapture(){ |
||||
|
||||
try { |
||||
canceled=false; |
||||
File tempFile = new File(SCREEN_CAPTURE_LOCA); |
||||
ScreenCapture capture = ScreenCapture.getInstance(); |
||||
capture.captureImage(); |
||||
if(canceled){ |
||||
return false; |
||||
} |
||||
JLabel imagebox = new JLabel(); |
||||
imagebox.setIcon(capture.getPickedIcon()); |
||||
capture.saveToFile(tempFile); |
||||
System.out.println("Over"); |
||||
|
||||
return true; |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private ScreenCapture() { |
||||
|
||||
try { |
||||
robot = new Robot(); |
||||
} catch (AWTException e) { |
||||
System.err.println("Internal Error: " + e); |
||||
e.printStackTrace(); |
||||
} |
||||
JPanel cp = (JPanel) dialog.getContentPane(); |
||||
cp.setLayout(new BorderLayout()); |
||||
labFullScreenImage.addMouseListener(new MouseAdapter() { |
||||
public void mouseReleased(MouseEvent evn) { |
||||
if (evn.getButton()==MouseEvent.BUTTON3){ |
||||
canceled=true; |
||||
System.out.println("captureCancel"); |
||||
|
||||
dialog.setVisible(false); |
||||
return; |
||||
} |
||||
isFirstPoint = true; |
||||
pickedImage = fullScreenImage.getSubimage(recX, recY, recW, |
||||
recH); |
||||
dialog.setVisible(false); |
||||
|
||||
} |
||||
}); |
||||
|
||||
|
||||
labFullScreenImage.addMouseMotionListener(new MouseMotionAdapter() { |
||||
public void mouseDragged(MouseEvent evn) { |
||||
if (isFirstPoint) { |
||||
x1 = evn.getX(); |
||||
y1 = evn.getY(); |
||||
isFirstPoint = false; |
||||
} else { |
||||
x2 = evn.getX(); |
||||
y2 = evn.getY(); |
||||
int maxX = Math.max(x1, x2); |
||||
int maxY = Math.max(y1, y2); |
||||
int minX = Math.min(x1, x2); |
||||
int minY = Math.min(y1, y2); |
||||
recX = minX; |
||||
recY = minY; |
||||
recW = maxX - minX; |
||||
recH = maxY - minY; |
||||
labFullScreenImage.drawRectangle(recX, recY, recW, recH); |
||||
} |
||||
} |
||||
|
||||
public void mouseMoved(MouseEvent e) { |
||||
labFullScreenImage.drawCross(e.getX(), e.getY()); |
||||
//messageLabel.setLocation(e.getX(), e.getY());
|
||||
} |
||||
}); |
||||
|
||||
cp.add(BorderLayout.CENTER, labFullScreenImage); |
||||
//cp.add(messageLabel);
|
||||
dialog.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); |
||||
dialog.setAlwaysOnTop(true); |
||||
dialog.setMaximumSize(Toolkit.getDefaultToolkit().getScreenSize()); |
||||
dialog.setUndecorated(true); |
||||
dialog.setSize(dialog.getMaximumSize()); |
||||
dialog.setModal(true); |
||||
} |
||||
|
||||
// Singleton Pattern
|
||||
public static ScreenCapture getInstance() { |
||||
return defaultCapturer; |
||||
} |
||||
|
||||
/** 捕捉屏幕的一个矫形区域 */ |
||||
public void captureImage() { |
||||
fullScreenImage = robot.createScreenCapture(new Rectangle(Toolkit |
||||
.getDefaultToolkit().getScreenSize())); |
||||
ImageIcon icon = new ImageIcon(fullScreenImage); |
||||
labFullScreenImage.setIcon(icon); |
||||
dialog.setVisible(true); |
||||
} |
||||
|
||||
/** 得到捕捉后的BufferedImage */ |
||||
public BufferedImage getPickedImage() { |
||||
return pickedImage; |
||||
} |
||||
|
||||
/** 得到捕捉后的Icon */ |
||||
public ImageIcon getPickedIcon() { |
||||
return new ImageIcon(getPickedImage()); |
||||
} |
||||
|
||||
/** |
||||
* 储存为一个文件,为PNG格式 |
||||
* |
||||
* @deprecated replaced by saveAsPNG(File file) |
||||
**/ |
||||
@Deprecated |
||||
public void saveToFile(File file) throws IOException { |
||||
ImageIO.write(getPickedImage(), defaultImageFormater, file); |
||||
} |
||||
|
||||
|
||||
/** 写入一个OutputStream */ |
||||
public void write(OutputStream out) throws IOException { |
||||
ImageIO.write(getPickedImage(), defaultImageFormater, out); |
||||
} |
||||
|
||||
// singleton design pattern
|
||||
private static ScreenCapture defaultCapturer = new ScreenCapture(); |
||||
private int x1, y1, x2, y2; |
||||
private int recX, recY, recH, recW; // 截取的图像
|
||||
private boolean isFirstPoint = true; |
||||
private BackgroundImage labFullScreenImage = new BackgroundImage(); |
||||
//private Label messageLabel = new Label("按任意键可退出。");
|
||||
private Robot robot; |
||||
private BufferedImage fullScreenImage; |
||||
private BufferedImage pickedImage; |
||||
private String defaultImageFormater = "png"; |
||||
private JDialog dialog = new JDialog(); |
||||
} |
||||
|
||||
/** 显示图片的Label */ |
||||
class BackgroundImage extends JLabel { |
||||
public void paintComponent(Graphics g) { |
||||
super.paintComponent(g); |
||||
g.drawRect(x, y, w, h); |
||||
String area = w + " * " + h; |
||||
g.drawString(area, x + w / 2 - 15, y + h / 2); |
||||
g.drawLine(lineX, 0, lineX, getHeight()); |
||||
|
||||
g.drawLine(0, lineY, getWidth(), lineY); |
||||
} |
||||
|
||||
public void drawRectangle(int x, int y, int width, int height) { |
||||
this.x = x; |
||||
this.y = y; |
||||
h = height; |
||||
w = width; |
||||
repaint(); |
||||
} |
||||
|
||||
public void drawCross(int x, int y) { |
||||
lineX = x; |
||||
lineY = y; |
||||
repaint(); |
||||
} |
||||
|
||||
int lineX, lineY; |
||||
int x, y, h, w; |
||||
} |
@ -0,0 +1,245 @@ |
||||
package me.lensferno.dogename.utils.ocr; |
||||
|
||||
import javafx.application.Platform; |
||||
import javafx.beans.property.SimpleBooleanProperty; |
||||
import javafx.beans.property.SimpleStringProperty; |
||||
import javafx.scene.Scene; |
||||
import javafx.scene.image.Image; |
||||
import javafx.scene.image.ImageView; |
||||
import javafx.scene.input.KeyCode; |
||||
import javafx.scene.layout.Pane; |
||||
import javafx.scene.shape.Line; |
||||
import javafx.stage.Stage; |
||||
|
||||
import javax.imageio.ImageIO; |
||||
import java.awt.*; |
||||
import java.awt.image.BufferedImage; |
||||
import java.io.ByteArrayInputStream; |
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.File; |
||||
|
||||
public class ScreenCapture { |
||||
|
||||
private OcrTool ocrTool; |
||||
|
||||
private final String cacheImageFileLocation = "caches/image/ocrImageCache.jpg"; |
||||
|
||||
private final Runnable finalEvent = new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
if (ocrTool == null) { |
||||
ocrTool = new OcrTool(); |
||||
} |
||||
ocrTool.requestOcrAPI(cacheImageFileLocation); |
||||
result.set(ocrTool.getResult()); |
||||
end.set(true); |
||||
} |
||||
}; |
||||
|
||||
private final SimpleStringProperty result = new SimpleStringProperty(); |
||||
private final SimpleBooleanProperty end = new SimpleBooleanProperty(true); |
||||
|
||||
private final ImageView screenImageView = new ImageView(); |
||||
private final Pane rootPane = new Pane(); |
||||
private final Stage stage = new Stage(); |
||||
|
||||
private final int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width; |
||||
private final int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height; |
||||
|
||||
ScreenshotTool screenshotTool = new ScreenshotTool(); |
||||
|
||||
public void startCapture() { |
||||
end.set(false); |
||||
Image fullscreenImage = screenshotTool.getFullScreenshotImageData(); |
||||
createScreenCaptureWindow(fullscreenImage); |
||||
} |
||||
|
||||
public void createScreenCaptureWindow(Image screenImage) { |
||||
this.screenImageView.setImage(screenImage); |
||||
stage.setFullScreen(true); |
||||
stage.setAlwaysOnTop(true); |
||||
stage.setFullScreenExitHint("拖动鼠标选择需要截取识别的区域,\n按ESC键可退出截屏选取"); |
||||
//stage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
|
||||
|
||||
rootPane.setPrefWidth(screenWidth); |
||||
rootPane.setPrefHeight(screenHeight); |
||||
rootPane.getChildren().add(screenImageView); |
||||
screenImageView.setFitWidth(screenWidth); |
||||
screenImageView.setFitHeight(screenHeight); |
||||
|
||||
Scene scene = new Scene(rootPane, screenWidth, screenHeight); |
||||
//rootPane.setStyle("-fx-background-color: black");
|
||||
scene.setOnKeyPressed(e -> { |
||||
if (e.getCode().equals(KeyCode.ESCAPE)){ |
||||
stage.close(); |
||||
end.set(true); |
||||
} |
||||
}); |
||||
|
||||
this.addMouseLine(); |
||||
scene.setOnMouseMoved(e -> this.drawMouseLine(e.getX(), e.getY())); |
||||
|
||||
this.addEventListeners(); |
||||
|
||||
stage.setScene(scene); |
||||
stage.show(); |
||||
} |
||||
|
||||
private double dragStartX = 0; |
||||
private double dragStartY = 0; |
||||
|
||||
private double dragEndX = 0; |
||||
private double dragEndY = 0; |
||||
|
||||
private double selectedAreaWidth = 0; |
||||
private double selectedAreaHeight = 0; |
||||
|
||||
private Line Width_Follow; |
||||
private Line Height_Follow; |
||||
private Line Width_Fixed; |
||||
private Line Height_Fixed; |
||||
|
||||
private void addEventListeners() { |
||||
rootPane.setOnMousePressed(e -> { |
||||
dragStartX = e.getX(); |
||||
dragStartY = e.getY(); |
||||
this.createNewSelectedAreaRectangle(); |
||||
this.setLinePosition(); |
||||
}); |
||||
rootPane.setOnMouseDragged(e -> { |
||||
this.drawMouseLine(e.getX(), e.getY()); |
||||
this.drawSelectedAreaRectangle(e.getX(), e.getY()); |
||||
}); |
||||
rootPane.setOnMouseReleased(e -> { |
||||
dragEndX = e.getX(); |
||||
dragEndY = e.getY(); |
||||
int clipPositionX = (int)dragStartX; |
||||
int clipPositionY = (int)dragStartY; |
||||
if (selectedAreaWidth < 0) { |
||||
clipPositionX = (int)dragEndX; |
||||
} |
||||
if (selectedAreaHeight < 0) { |
||||
clipPositionY = (int)dragEndY; |
||||
} |
||||
try { |
||||
this.saveImage(clipPositionX, clipPositionY, Math.abs((int)selectedAreaWidth), Math.abs((int)selectedAreaHeight)); |
||||
this.runFinalEvent(finalEvent); |
||||
} catch (Exception exc) { |
||||
exc.printStackTrace(); |
||||
} finally { |
||||
stage.close(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
private void runFinalEvent(Runnable finalEvent) { |
||||
Platform.runLater(finalEvent); |
||||
} |
||||
|
||||
private void saveImage(int x, int y, int width, int height){ |
||||
try { |
||||
File outputFile = new File(cacheImageFileLocation); |
||||
File outputDir = outputFile.getParentFile(); |
||||
|
||||
if (!outputDir.exists()) { |
||||
outputDir.mkdirs(); |
||||
outputFile.createNewFile(); |
||||
} |
||||
screenshotTool.saveClippedImage(x, y, width, height, "png", outputFile); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
private void createNewSelectedAreaRectangle() { |
||||
Width_Follow = new Line(); |
||||
Height_Follow = new Line(); |
||||
Width_Fixed = new Line(); |
||||
Height_Fixed = new Line(); |
||||
|
||||
Width_Follow.setStrokeWidth(5); |
||||
Height_Follow.setStrokeWidth(5); |
||||
Width_Fixed.setStrokeWidth(5); |
||||
Height_Fixed.setStrokeWidth(5); |
||||
|
||||
rootPane.getChildren().addAll(Width_Follow, Height_Follow, Width_Fixed, Height_Fixed); |
||||
} |
||||
|
||||
private void setLinePosition() { |
||||
Width_Fixed.layoutXProperty().set(dragStartX); |
||||
Width_Fixed.layoutYProperty().set(dragStartY); |
||||
|
||||
Height_Fixed.layoutYProperty().set(dragStartY); |
||||
Height_Fixed.layoutXProperty().set(dragStartX); |
||||
|
||||
Width_Follow.layoutXProperty().set(dragStartX); |
||||
Width_Follow.layoutYProperty().set(dragStartY); |
||||
|
||||
Height_Follow.layoutXProperty().set(dragStartX); |
||||
Height_Follow.layoutYProperty().set(dragStartY); |
||||
} |
||||
|
||||
private final Line MouseLine_X = new Line(); |
||||
private final Line MouseLine_Y = new Line(); |
||||
|
||||
private void addMouseLine() { |
||||
MouseLine_X.layoutXProperty().set(0); |
||||
MouseLine_X.endXProperty().set(screenWidth); |
||||
|
||||
MouseLine_Y.layoutYProperty().set(0); |
||||
MouseLine_Y.endYProperty().set(screenHeight); |
||||
|
||||
rootPane.getChildren().addAll(MouseLine_X, MouseLine_Y); |
||||
} |
||||
|
||||
private void drawMouseLine(double mouseX, double mouseY) { |
||||
MouseLine_X.setLayoutY(mouseY); |
||||
MouseLine_Y.setLayoutX(mouseX); |
||||
} |
||||
|
||||
private void drawSelectedAreaRectangle(double mouseX, double mouseY) { |
||||
|
||||
// 通过计算鼠标起始和当前坐标来确定四根线的长度和位置
|
||||
selectedAreaWidth = mouseX - dragStartX; |
||||
selectedAreaHeight = mouseY - dragStartY; |
||||
|
||||
Width_Fixed.endXProperty().set(selectedAreaWidth); |
||||
Height_Fixed.endYProperty().set(selectedAreaHeight); |
||||
|
||||
Width_Follow.layoutYProperty().set(mouseY); |
||||
Height_Follow.layoutXProperty().set(mouseX); |
||||
|
||||
Width_Follow.endXProperty().set(selectedAreaWidth); |
||||
Height_Follow.endYProperty().set(selectedAreaHeight); |
||||
} |
||||
|
||||
class ScreenshotTool { |
||||
BufferedImage fullscreenBufferedImage; |
||||
public Image getFullScreenshotImageData() { |
||||
try { |
||||
Robot robot = new Robot(); |
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); |
||||
|
||||
fullscreenBufferedImage = robot.createScreenCapture(new Rectangle(screenWidth, screenHeight)); |
||||
ImageIO.write(fullscreenBufferedImage, "png", byteArrayOutputStream); |
||||
|
||||
return new Image(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public void saveClippedImage(int x, int y, int width, int height, String formateName, File output) throws Exception{ |
||||
ImageIO.write(fullscreenBufferedImage.getSubimage(x, y, width, height), formateName, output); |
||||
} |
||||
} |
||||
|
||||
public SimpleStringProperty resultProperty() { |
||||
return result; |
||||
} |
||||
|
||||
public SimpleBooleanProperty endProperty() { |
||||
return end; |
||||
} |
||||
} |
Loading…
Reference in new issue