Skip to content
Snippets Groups Projects
Commit 0e90f26c authored by aburn's avatar aburn
Browse files

Added rotation awareness to image view miniature

parent 2c22f707
Branches
No related merge requests found
...@@ -12,127 +12,144 @@ In this respect, the user's attention is drawn to the risks associated with load ...@@ -12,127 +12,144 @@ In this respect, the user's attention is drawn to the risks associated with load
The fact that you are presently reading this means that you have had knowledge of the CeCILL license and that you accept its terms. The fact that you are presently reading this means that you have had knowledge of the CeCILL license and that you accept its terms.
*/ */
package org.interreg.docexplore.gui.image; package org.interreg.docexplore.gui.image;
import java.awt.AlphaComposite; import java.awt.AlphaComposite;
import java.awt.BasicStroke; import java.awt.BasicStroke;
import java.awt.Color; import java.awt.Color;
import java.awt.Composite; import java.awt.Composite;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.RenderingHints; import java.awt.RenderingHints;
import java.awt.Stroke; import java.awt.Stroke;
import java.awt.event.ComponentAdapter; import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent; import java.awt.event.ComponentEvent;
import java.awt.image.BufferedImage; import java.awt.geom.AffineTransform;
import java.util.TimerTask; import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
public class ImageView extends EditorView import java.util.TimerTask;
{
private static final long serialVersionUID = -7152689573523551765L; public class ImageView extends EditorView
{
protected BufferedImage image = null; private static final long serialVersionUID = -7152689573523551765L;
public ImageView() {this(null);} protected BufferedImage image = null;
public ImageView(EditorView.Operation<? extends ImageView> defaultOperation)
{ public ImageView() {this(null);}
super(defaultOperation); public ImageView(EditorView.Operation<? extends ImageView> defaultOperation)
{
addComponentListener(new ComponentAdapter() super(defaultOperation);
{
@Override public void componentResized(ComponentEvent e) addComponentListener(new ComponentAdapter()
{ {
if (getScale() == 0) @Override public void componentResized(ComponentEvent e)
fit(); {
} if (getScale() == 0)
}); fit();
} }
});
protected void constrain() }
{
if (image != null) protected void constrain()
{ {
x0 = Math.max(0, Math.min(getImageWidth(), x0)); if (image != null)
y0 = Math.max(0, Math.min(getImageHeight(), y0)); {
scale = Math.max(.01, Math.min(20, scale)); x0 = Math.max(0, Math.min(getImageWidth(), x0));
} y0 = Math.max(0, Math.min(getImageHeight(), y0));
} scale = Math.max(.01, Math.min(20, scale));
}
public void setImage(BufferedImage image) {setImage(image, true);} }
public void setImage(BufferedImage image, boolean fit)
{ public void setImage(BufferedImage image) {setImage(image, true);}
this.image = image; public void setImage(BufferedImage image, boolean fit)
if (fit) {
fit(); this.image = image;
} if (fit)
public BufferedImage getImage() {return image;} fit();
public int getImageWidth() {return image != null ? image.getWidth() : -1;} }
public int getImageHeight() {return image != null ? image.getHeight() : -1;} public BufferedImage getImage() {return image;}
public BufferedImage getSubImage(int x, int y, int w, int h) {return image.getSubimage(x, y, w, h);} public int getImageWidth() {return image != null ? image.getWidth() : -1;}
public int getImageHeight() {return image != null ? image.getHeight() : -1;}
Stroke outline = new BasicStroke(1f); public BufferedImage getSubImage(int x, int y, int w, int h) {return image.getSubimage(x, y, w, h);}
float miniSizeFactor = .1f;
@Override protected void drawView(Graphics2D g, double pixelSize) Stroke outline = new BasicStroke(1f);
{ float miniSizeFactor = .1f;
if (image != null) @Override protected void drawView(Graphics2D g, double pixelSize)
{ {
drawImage(g, pixelSize); if (image != null)
drawMini(g, pixelSize); {
} drawImage(g, pixelSize);
super.drawView(g, pixelSize); drawMini(g, pixelSize);
} }
super.drawView(g, pixelSize);
protected void drawImage(Graphics2D g, double pixelSize) }
{
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); protected void drawImage(Graphics2D g, double pixelSize)
g.drawImage(image, 0, 0, null); {
} g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.drawImage(image, 0, 0, null);
}
float miniAlpha = 0; float miniAlpha = 0;
protected void drawMini(Graphics2D g, double pixelSize) protected AffineTransform miniTransform = new AffineTransform();
Point2D br = new Point2D.Double(), brt = new Point2D.Double();
protected void drawMini(Graphics2D g, double pixelSize)
{ {
int iw = getImageWidth(), ih = getImageHeight(); int iw = getImageWidth(), ih = getImageHeight();
double l = Math.max(0, Math.min(1, toViewX(0)/iw)), r = Math.max(0, Math.min(1, toViewX(getWidth())/iw)); double lt = Math.max(0, Math.min(1, toViewX(0, 0)/iw)), rt = Math.max(0, Math.min(1, toViewX(getWidth(), getHeight())/iw));
double u = Math.max(0, Math.min(1, toViewY(0)/ih)), d = Math.max(0, Math.min(1, toViewY(getHeight())/ih)); double ut = Math.max(0, Math.min(1, toViewY(0, 0)/ih)), dt = Math.max(0, Math.min(1, toViewY(getWidth(), getHeight())/ih));
double l = Math.min(lt, rt), r = Math.max(lt, rt);
float talpha = (r-l)*(d-u) < 1 ? 1 : 0; double u = Math.min(ut, dt), d = Math.max(ut, dt);
if (talpha != miniAlpha)
miniAlpha = Math.max(talpha < miniAlpha ? talpha : 0, Math.min(talpha > miniAlpha ? talpha : 1, miniAlpha+(talpha < miniAlpha ? -.1f : .1f))); float talpha = (r-l)*(d-u) < 1 ? 1 : 0;
if (talpha != miniAlpha)
if (miniAlpha > 0) miniAlpha = Math.max(talpha < miniAlpha ? talpha : 0, Math.min(talpha > miniAlpha ? talpha : 1, miniAlpha+(talpha < miniAlpha ? -.1f : .1f)));
if (miniAlpha > 0)
{ {
g.setTransform(defaultTransform);
Stroke oldStroke = g.getStroke();
g.setStroke(outline);
Composite oldComposite = g.getComposite();
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, miniAlpha));
float miniSize = miniSizeFactor*Math.min(getWidth(), getHeight()); float miniSize = miniSizeFactor*Math.min(getWidth(), getHeight());
float mw = iw < ih ? miniSize : iw*miniSize/ih; float mw = iw < ih ? miniSize : iw*miniSize/ih;
float mh = iw < ih ? ih*miniSize/iw : miniSize; float mh = iw < ih ? ih*miniSize/iw : miniSize;
renderMini(g, pixelSize, (int)mw, (int)mh);
g.setColor(Color.white); miniTransform.setTransform(defaultTransform);
g.drawRect(0, 0, (int)mw, (int)mh); if (rot != ViewRotation.None)
g.setColor(Color.blue); {
g.drawRect((int)(l*mw), (int)(u*mh), (int)((r-l)*mw), (int)((d-u)*mh)); miniTransform.quadrantRotate(-rot.ordinal(), 0, 0);
br.setLocation(mw, mh);
g.setComposite(oldComposite); miniTransform.transform(br, brt);
g.setStroke(oldStroke); miniTransform.setToTranslation(brt.getX() < 0 ? -brt.getX() : 0, brt.getY() < 0 ? -brt.getY() : 0);
g.setTransform(viewTransform); miniTransform.quadrantRotate(-rot.ordinal(), 0, 0);
} miniTransform.transform(br, brt);
}
if (miniAlpha != talpha) g.setTransform(miniTransform);
new Thread(repaintTask).start(); Stroke oldStroke = g.getStroke();
} g.setStroke(outline);
protected void renderMini(Graphics2D g, double pixelSize, int mw, int mh) Composite oldComposite = g.getComposite();
{ g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, miniAlpha));
g.drawImage(image, 0, 0, mw, mh, null);
} renderMini(g, pixelSize, (int)mw, (int)mh);
Runnable repaintTask = new TimerTask() {@Override public void run() {try {Thread.sleep(30);} catch (Exception e) {} repaint();}};
g.setColor(Color.white);
public void fit() g.drawRect(0, 0, (int)mw, (int)mh);
{ g.setColor(Color.blue);
if (image != null) g.drawRect((int)(l*mw), (int)(u*mh), (int)((r-l)*mw), (int)((d-u)*mh));
fitView(0, 0, getImageWidth(), getImageHeight(), .05);
} g.setComposite(oldComposite);
} g.setStroke(oldStroke);
g.setTransform(viewTransform);
}
if (miniAlpha != talpha)
new Thread(repaintTask).start();
}
protected void renderMini(Graphics2D g, double pixelSize, int mw, int mh)
{
g.drawImage(image, 0, 0, mw, mh, null);
}
Runnable repaintTask = new TimerTask() {@Override public void run() {try {Thread.sleep(30);} catch (Exception e) {} repaint();}};
public void fit()
{
if (image != null)
fitView(0, 0, getImageWidth(), getImageHeight(), .05);
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment