/*! Copyright (C) 2009 Apertus, All Rights Reserved
*! Author : Apertus Team
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*!
-----------------------------------------------------------------------------**/
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Rectangle;
public class GuidesOverlay extends javax.swing.JFrame implements javax.swing.RootPaneContainer {
private boolean DrawCenterX = false;
private boolean DrawOuterX = false;
private boolean DrawThirds = false;
private boolean DrawSafeArea = false;
int crosshair_length = 3; // in percent of image
ElphelVision Parent;
public GuidesOverlay(GraphicsConfiguration gc, ElphelVision parent) {
super(gc);
Parent = parent;
initComponents();
jPanel1.setOpaque(false);
setAlwaysOnTop(true);
setLocationRelativeTo(null);
}
public void SetOptions(boolean drawCenterX, boolean drawOuterX, boolean drawThirds, boolean drawSafeArea) {
this.DrawCenterX = drawCenterX;
this.DrawOuterX = drawOuterX;
this.DrawThirds = drawThirds;
this.DrawSafeArea = drawSafeArea;
jPanel1.repaint();
}
public void SetOptions(boolean[] inval) {
this.DrawCenterX = inval[0];
this.DrawOuterX = inval[1];
this.DrawThirds = inval[2];
this.DrawSafeArea = inval[3];
jPanel1.repaint();
}
public void SetVisibility(boolean visible) {
this.setVisible(visible);
}
private void paintoverlay(Graphics g) {
Parent.UpdateOverlayPosition();
Graphics2D g2 = (Graphics2D) g;
g.setPaintMode();
float aspect_ratio = Parent.Camera.GetVideoAspectRatio();
Rectangle bound = this.getBounds();
// TODO the situation when video is taller than viewing area
// video is wider than viewing area
float correctionfactor_height = 1.0f - ((float) bound.width / aspect_ratio / (float) bound.height);
int cross_x = (int) (crosshair_length / 100.0f * this.getWidth());
int cross_y = (int) (crosshair_length / 100.0f * this.getHeight());
// Apparently there is no official guideline for the size of the action safe area
// The BBC suggests 5% per side so I guess that is good for us :)
//http://en.wikipedia.org/wiki/Overscan
int croppercentage = 95;
float a = correctionfactor_height / 2.0f * (float) this.getHeight();
float b = ((float) this.getHeight() * (1.0f - correctionfactor_height) * (100.0f - croppercentage) / 100.0f);
if (DrawCenterX) {
DrawShadowedLine(g2, this.getWidth() / 2 - cross_x / 2, this.getHeight() / 2, this.getWidth() / 2 + cross_x / 2, this.getHeight() / 2); //vertical
DrawShadowedLine(g2, this.getWidth() / 2, this.getHeight() / 2 - cross_x / 2, this.getWidth() / 2, this.getHeight() / 2 + cross_x / 2); // horizontal
}
if (DrawOuterX) {
DrawShadowedLine(g2, 0, this.getHeight() / 2, cross_x, this.getHeight() / 2); // left
DrawShadowedLine(g2, this.getWidth() - cross_x, this.getHeight() / 2, this.getWidth(), this.getHeight() / 2); // right
DrawShadowedLine(g2, this.getWidth() / 2, (int) (correctionfactor_height / 2 * this.getHeight()), this.getWidth() / 2, (int) (correctionfactor_height / 2 * this.getHeight() + cross_y)); // top
DrawShadowedLine(g2, this.getWidth() / 2, (int) (this.getHeight() - (correctionfactor_height / 2 * this.getHeight())) - cross_y, this.getWidth() / 2, (int) (this.getHeight() - (correctionfactor_height / 2 * this.getHeight()))); // bottom
}
if (DrawThirds) {
int Y1 = (int) (a + (1.0f / 3.0f * ((float) this.getHeight() - (2.0f * a))));
int Y2 = (int) (a + (2.0f / 3.0f * ((float) this.getHeight() - (2.0f * a))));
DrawShadowedLine(g2, 0, Y1, this.getWidth(), Y1); // horizontal
DrawShadowedLine(g2, 0, Y2, this.getWidth(), Y2); // horizontal
DrawShadowedLine(g2, this.getWidth() / 3, (int) a, this.getWidth() / 3, this.getHeight() - (int) a); // vertical
DrawShadowedLine(g2, this.getWidth() * 2 / 3, (int) a, this.getWidth() * 2 / 3, this.getHeight() - (int) a); // vertical
}
if (DrawSafeArea) {
int X1 = (int) (this.getWidth() * (100 - croppercentage) / 100);
int Y1 = (int) (a + b);
int X2 = (int) (this.getWidth() * croppercentage / 100);
int Y2 = Y1;
int X3 = X2;
int Y3 = (int) (this.getHeight() - a - b);
int X4 = X1;
int Y4 = Y3;
DrawShadowedLine(g2, X1, Y1, X2, Y2); // top
DrawShadowedLine(g2, X2, Y2, X3, Y3); // right
DrawShadowedLine(g2, X3, Y3, X4, Y4); // bottom
DrawShadowedLine(g2, X4, Y4, X1, Y1); // left
//DrawShadowedLine(g2, this.getWidth() * (100 - croppercentage) / 100, this.getHeight() * (100 - croppercentage) / 100, this.getWidth() * (100 - croppercentage) / 100, this.getHeight() * croppercentage / 100); // left
//DrawShadowedLine(g2, this.getWidth() * croppercentage / 100, this.getHeight() * (100 - croppercentage) / 100, this.getWidth() * croppercentage / 100, this.getHeight() * croppercentage / 100); // right
}
}
private void DrawShadowedLine(Graphics2D g2, int StartX, int StartY, int EndX, int EndY) {
g2.setStroke(new BasicStroke(1));
g2.setColor(new Color(0, 0, 0, 200));
if (StartY == EndY) {
// horizontal
g2.drawLine(StartX, StartY + 1, EndX, EndY + 1);
g2.drawLine(StartX, StartY - 1, EndX, EndY - 1);
}
if (StartX == EndX) {
// vertical
g2.drawLine(StartX + 1, StartY, EndX + 1, EndY);
g2.drawLine(StartX - 1, StartY, EndX - 1, EndY);
}
g2.setColor(new Color(255, 255, 255, 200));
g2.drawLine(StartX, StartY, EndX, EndY);
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jPanel1 = new javax.swing.JPanel() {
protected void paintComponent(Graphics g) {
if (g instanceof Graphics2D) {
paintoverlay(g);
} else {
super.paintComponent(g);
}
}
}
;
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setMinimumSize(new java.awt.Dimension(321, 250));
setResizable(false);
setUndecorated(true);
jPanel1.setDoubleBuffered(false);
jPanel1.setOpaque(false);
jPanel1.setLayout(new java.awt.BorderLayout());
getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER);
pack();
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel jPanel1;
// End of variables declaration//GEN-END:variables
}