/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.java.sip.communicator.plugin.desktoputil.presence.avatar.imagepicker;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.event.*;
import net.java.sip.communicator.plugin.desktoputil.*;
/**
* The <tt>EditPanel</tt> manage the image size and the clipper component
*
* @author Damien Roth
* @author Shashank Tyagi
*/
public class EditPanel
extends TransparentPanel
implements ChangeListener,
ActionListener
{
private ImageClipper imageClipper;
private BufferedImage image;
private JSlider imageSizeSlider;
private JButton zoomIn, zoomOut, reset;
private boolean resizeOnWidth = true;
private boolean smallImage = false;
// Clipping zone dimension
private int clippingZoneWidth = 96;
private int clippingZoneHeight = 96;
/**
* Create a new <tt>EditPanel</tt>
*
* @param clippingZoneWidth the width of the clipping zone
* @param clippingZoneHeight the height of the clipping zone
*/
public EditPanel(int clippingZoneWidth, int clippingZoneHeight)
{
super();
this.setLayout(new BorderLayout());
this.clippingZoneWidth = clippingZoneWidth;
this.clippingZoneHeight = clippingZoneHeight;
this.zoomOut = new JButton(DesktopUtilActivator.getResources()
.getImage("service.gui.buttons.ZOOM_OUT"));
this.zoomOut.addActionListener(this);
this.zoomIn = new JButton(DesktopUtilActivator.getResources()
.getImage("service.gui.buttons.ZOOM_IN"));
this.zoomIn.addActionListener(this);
this.reset = new JButton(DesktopUtilActivator.getResources()
.getImage("service.gui.buttons.RESET"));
this.reset.setToolTipText(DesktopUtilActivator.getResources()
.getI18NString("service.gui.avatar.imagepicker.RESET"));
this.reset.addActionListener(this);
imageSizeSlider = new JSlider(clippingZoneWidth, clippingZoneWidth,
clippingZoneWidth);
imageSizeSlider.addChangeListener(this);
imageSizeSlider.setOpaque(false);
imageSizeSlider.setToolTipText(DesktopUtilActivator.getResources()
.getI18NString("service.gui.avatar.imagepicker.IMAGE_SIZE"));
TransparentPanel sliderPanel = new TransparentPanel();
sliderPanel.add(zoomOut);
sliderPanel.add(this.imageSizeSlider);
sliderPanel.add(this.zoomIn);
sliderPanel.add(this.reset);
this.imageClipper = new ImageClipper(this.clippingZoneWidth,
this.clippingZoneHeight);
this.add(imageClipper, BorderLayout.CENTER);
this.add(sliderPanel, BorderLayout.SOUTH);
}
/**
* Sets the image to be edited
*
* @param image the image to be edited
*/
public void setImage(BufferedImage image)
{
int width = image.getWidth(null);
int height = image.getHeight(null);
// Checks if one dimension of the image is smaller than the clipping zone
if (width < this.clippingZoneWidth || height < this.clippingZoneHeight)
{
// Disable the slider used to set the size of the image
this.enableSlider(false);
this.smallImage = true;
/* Resize the image to match the clipping zone
* First case :
* * Image wider than high and the clipping zone
* * Image wider than high and included in the clipping zone
* Second case :
* * Image higher than wide and the clipping zone
* * Image wider than high and included in the clipping zone
*/
if ((width > height && width > this.clippingZoneWidth)
|| (height > width && height <= this.clippingZoneHeight))
{
this.image = ImageUtils.getBufferedImage(
image.getScaledInstance(
-1, this.clippingZoneHeight, Image.SCALE_SMOOTH));
}
else
{
this.image = ImageUtils.getBufferedImage(
image.getScaledInstance(
this.clippingZoneWidth, -1, Image.SCALE_SMOOTH));
}
}
else
{
this.image = image;
this.enableSlider(true);
this.resizeOnWidth = !(height < width);
this.imageSizeSlider.setMaximum(Math.min(width, height));
}
SwingUtilities.invokeLater(new Runnable() {
public void run()
{
reset();
}
});
}
/**
* Reset the editor
*/
public void reset()
{
imageSizeSlider.setValue(this.imageSizeSlider.getMinimum());
drawImage();
}
/**
* Returns the clipped image.
*
* @return the clipped image
*/
public byte[] getClippedImage()
{
BufferedImage fullImage = getResizedImage(true);
if(fullImage == null)
return null;
Rectangle clipping = this.imageClipper.getCroppedArea();
BufferedImage subImage = fullImage.getSubimage(clipping.x, clipping.y,
clipping.width, clipping.height);
byte[] result = ImageUtils.toByteArray(subImage);
return result;
}
/**
* Resize the image.
* @param hq
* @return
*/
private BufferedImage getResizedImage(boolean hq)
{
if(this.image == null)
return null;
BufferedImage i = null;
int size = this.imageSizeSlider.getValue();
if (this.resizeOnWidth)
{
i = ImageUtils.getBufferedImage(
this.image.getScaledInstance(
size,
-1,
(hq) ? Image.SCALE_SMOOTH : Image.SCALE_FAST));
}
else
{
i = ImageUtils.getBufferedImage(
this.image.getScaledInstance(
-1,
size,
(hq) ? Image.SCALE_SMOOTH : Image.SCALE_FAST));
}
return i;
}
/**
* Draw the image.
*/
private void drawImage()
{
// Use high quality scalling when the image is smaller than the clipper
this.imageClipper.setImage(getResizedImage(smallImage));
}
private void enableSlider(boolean enabled)
{
this.imageSizeSlider.setEnabled(enabled);
this.zoomIn.setEnabled(enabled);
this.zoomOut.setEnabled(enabled);
this.reset.setEnabled(enabled);
}
/**
* New size image selected update the clipper.
* @param e the event.
*/
public void stateChanged(ChangeEvent e)
{
drawImage();
}
/**
* Listens for button actions.
* @param e
*/
public void actionPerformed(ActionEvent e)
{
if(e.getSource().equals(zoomIn))
{
if(imageSizeSlider.getValue() < imageSizeSlider.getMaximum())
{
imageSizeSlider.setValue(imageSizeSlider.getValue() + 1);
drawImage();
}
}
else if(e.getSource().equals(zoomOut))
{
if(imageSizeSlider.getValue() > imageSizeSlider.getMinimum())
{
imageSizeSlider.setValue(imageSizeSlider.getValue() - 1);
drawImage();
}
}
else if(e.getSource().equals(reset))
{
reset();
}
}
}