プログラマメモ2 - programmer no memo2

角丸にチャレンジ 2007/11/03

角丸画像をつくります。javaです。
ドラッグアンドドロップで画像を渡して角丸にした画像を表示してみます。

仕様は
(1)ウインドウ画面を表示します。
(2)任意の画像をドラッグアンドドロップできます。
(3)ドロップされた画像を角丸にして表示します。

いろいろな方法で角丸ができると思いますが、
今回とった方法は、「Filty Rich Clients」のp.166のUsing SrcInを参考にしています。

Filthy Rich Clients: Developing Animated & Graphical Effects for Desktop Java Applications (The Java Series)
Filthy Rich Clients: Developing Animated & Graphical Effects for Desktop Java Applications (The Java Series)
Chet Haase Romain Guy

by G-Tools


まずドロップされた画像のサイズからGraphics生成して角丸レクタングルを作成します。
つぎに、compositeでドロップされた画像と合成します。

BufferedImageをnewして、Graphics2Dを作成する方法はいろいろ応用できそうです。

BufferedImage round = new BufferedImage(w, h,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = round.createGraphics();
// g2.setColor(Color.BLUE);
g2.fillRoundRect(0, 0, w, h, 37, 37);
g2.setComposite(AlphaComposite.SrcIn);
g2.drawImage(droppedImage, 0, 0, null);
g2.dispose();


おまけで、swingxのペインターをいろいろ使っています。

起動した画面


ドロップした画面


角丸の角丸がきれいではないです。

以下、ソースコードです。
package main.kadomaru;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;

import org.jdesktop.swingx.JXPanel;
import org.jdesktop.swingx.painter.AbstractLayoutPainter;
import org.jdesktop.swingx.painter.CompoundPainter;
import org.jdesktop.swingx.painter.ImagePainter;
import org.jdesktop.swingx.painter.RectanglePainter;

public class ImagePanel extends JXPanel {
static DataFlavor urlFlavor;
static {
try {
urlFlavor = new DataFlavor(
"application/x-java-url; class=java.net.URL");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

}

DropTarget dropTarget;
BufferedImage droppedImage;
private static final long serialVersionUID = 1L;

public ImagePanel() {
RectanglePainter roundRect = new RectanglePainter(10, 10, 10, 10, 37,
37, true, Color.black, 10, Color.ORANGE);
// roundRect.setAntialiasing(RenderingHints.VALUE_ANTIALIAS_ON);
CompoundPainter compound = new CompoundPainter(roundRect);
setBackgroundPainter(compound);
initialize();
dropTarget = new DropTarget(this, new MyDrop());
}

private void initialize() {
this.setSize(300, 200);
this.setLayout(new GridBagLayout());
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
paintSuggestion(g);
paintDropedImage(g);
}

protected void paintSuggestion(Graphics g) {
if (this.droppedImage != null)
return;
Dimension dimension = this.getSize();
int w = (int) (dimension.getWidth() / 2);
int h = (int) (dimension.getHeight() / 2);
Font font = new Font("", 0, 32);
g.setColor(Color.WHITE);
g.setFont(font);
g.drawString("Drop Image", 18, h);
}

protected void paintDropedImage(Graphics g) {
if (this.droppedImage == null)
return;

int w = droppedImage.getWidth();
int h = droppedImage.getHeight();

BufferedImage round = new BufferedImage(w, h,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = round.createGraphics();
// g2.setColor(Color.BLUE);
g2.fillRoundRect(0, 0, w, h, 37, 37);
g2.setComposite(AlphaComposite.SrcIn);
g2.drawImage(droppedImage, 0, 0, null);
g2.dispose();
ImagePainter painter = new ImagePainter(round,
AbstractLayoutPainter.HorizontalAlignment.CENTER,
AbstractLayoutPainter.VerticalAlignment.CENTER);
// painter.setScaleToFit(true);
painter.setAntialiasing(true);

CompoundPainter cp = new CompoundPainter(painter);
setBackgroundPainter(cp);
}

class MyDrop implements DropTargetListener {
public void dragEnter(DropTargetDragEvent dtde) {
}

public void dragExit(DropTargetEvent dte) {
}

public void dragOver(DropTargetDragEvent dtde) {
}

public void drop(DropTargetDropEvent dtde) {
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
Transferable transferable = dtde.getTransferable();
// dump(transferable);
boolean gotData = false;
if (transferable.isDataFlavorSupported(urlFlavor)) {
try {
URL url = (URL) transferable.getTransferData(urlFlavor);

BufferedImage tmpImage = ImageIO.read(url);
droppedImage = tmpImage;
repaint();
gotData = true;
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
dtde.dropComplete(gotData);
}
return;
}
}

public void dropActionChanged(DropTargetDragEvent dtde) {
}

public void dump(Transferable transferable) {
DataFlavor[] dataFlavors = transferable.getTransferDataFlavors();
for (int i = 0; i < dataFlavors.length; i++) {
DataFlavor flavor = dataFlavors[i];
System.out.println(flavor);
}
}
}

}

: