• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:MemoryImageSourceで配列から画像を生成
#navi(../)
#tags(BufferedImage, MouseListener, MouseMotionListener, MemoryImageSource)
RIGHT:Posted by &author(aterai); at 2010-06-07
*MemoryImageSourceで配列から画像を生成 [#n6e7348a]
---
category: swing
folder: MemoryImageSource
title: MemoryImageSourceで配列から画像を生成
tags: [BufferedImage, MouseListener, MouseMotionListener, MemoryImageSource]
author: aterai
pubdate: 2010-06-07T15:20:45+09:00
description: マウスのドラッグに応じて線を描画、消しゴムで消去する機能を実装します。
image: https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTPu_OEqoI/AAAAAAAAAec/z6MobKhblfI/s800/MemoryImageSource.png
---
* 概要 [#summary]
マウスのドラッグに応じて線を描画、消しゴムで消去する機能を実装します。

-&jnlp;
-&jar;
-&zip;
#download(https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTPu_OEqoI/AAAAAAAAAec/z6MobKhblfI/s800/MemoryImageSource.png)

//#screenshot
#ref(http://lh4.ggpht.com/_9Z4BYR88imo/TQTPu_OEqoI/AAAAAAAAAec/z6MobKhblfI/s800/MemoryImageSource.png)

**サンプルコード [#g703e7b6]
* サンプルコード [#sourcecode]
#code(link){{
int[] pixels = new int[320 * 240];
MemoryImageSource source = new MemoryImageSource(320, 240, pixels, 0, 320);
int penc = 0x0;
@Override public void paintComponent(Graphics g) {
// ...
@Override protected void paintComponent(Graphics g) {
  super.paintComponent(g);
  if(backImage!=null) {
    ((Graphics2D)g).drawImage(backImage, 0, 0, this);
  if (backImage != null) {
    ((Graphics2D) g).drawImage(backImage, 0, 0, this);
  }
  if(source!=null) {
  if (source != null) {
    g.drawImage(createImage(source), 0, 0, null);
  }
}

@Override public void mouseDragged(MouseEvent e) {
  Point pt = e.getPoint();
  double xDelta = e.getX() - startPoint.getX();
  double yDelta = e.getY() - startPoint.getY();
  double delta = Math.max(Math.abs(xDelta), Math.abs(yDelta));

  double xIncrement = xDelta / delta;
  double yIncrement = yDelta / delta;
  double xStart = startPoint.x;
  double yStart = startPoint.y;
  for(int i=0; i<delta; i++) {
    Point p = new Point((int)xStart, (int)yStart);
    if(p.x<0 || p.y<0 || p.x>=320 || p.y>=240) break;
  for (int i = 0; i < delta; i++) {
    Point p = new Point((int) xStart, (int) yStart);
    if (p.x < 0 || p.y < 0 || p.x >= 320 || p.y >= 240) break;
    pixels[p.x + p.y * 320] = penc;
    for(int n=-1;n<=1;n++) {
      for(int m=-1;m<=1;m++) {
        int t = (p.x+n) + (p.y+m) * 320;
        if(t>=0 && t<320*240) {
    for (int n = -1; n <= 1; n++) {
      for (int m = -1; m <= 1; m++) {
        int t = (p.x + n) + (p.y + m) * 320;
        if (t >= 0 && t < 320 * 240) {
          pixels[t] = penc;
        }
      }
    }
    repaint(p.x-2, p.y-2, 4, 4);
    repaint(p.x - 2, p.y - 2, 4, 4);
    xStart += xIncrement;
    yStart += yIncrement;
  }
  startPoint = pt;
}

@Override public void mousePressed(MouseEvent e) {
  startPoint = e.getPoint();
  penc = (e.getButton()==MouseEvent.BUTTON1)?0xff000000:0x0;
  penc = (e.getButton() == MouseEvent.BUTTON1) ? 0xff000000 : 0x0;
}
}}

**解説 [#n39bed19]
上記のサンプルでは、左クリックでドラッグすると黒で、右クリックでドラッグすると透過色(``0xff000000``、消しゴム)で、自由曲線を描画することができます。
``MemoryImageSource``に設定した画像の各ピクセルを表すint配列を、マウスのドラッグに応じて操作して``Image``を作成しています。
* 解説 [#explanation]
上記のサンプルでは、左クリックしてからドラッグすると黒、右クリックしてからドラッグすると透過色(`0xff000000`、消しゴム)で、自由曲線を描画できます。
`MemoryImageSource`に設定した画像の各ピクセルを表す`int`配列をマウスのドラッグに応じて操作して`Image`を作成しています。

----
以下のような方法もあります。
- 以下のように消しゴムとして`AlphaComposite.Clear`を使用する方法もある

#code{{
private static final Color ERASER = new Color(0,0,0,0);
private static final Color ERASER = new Color(0x0, true);
private boolean isPen = true;
private Point startPoint = new Point(-10,-10);
private Point startPoint = new Point(-10, -10);
private BufferedImage currentImage = null;
private BufferedImage backImage = null;
@Override public void paintComponent(Graphics g) {
@Override protected void paintComponent(Graphics g) {
  super.paintComponent(g);
  if(backImage!=null) {
  if (backImage != null) {
    g.drawImage(backImage, 0, 0, this);
  }
  if(currentImage!=null) {
  if (currentImage != null) {
    g.drawImage(currentImage, 0, 0, this);
  }
}

@Override public void mouseDragged(MouseEvent e) {
  Point pt = e.getPoint();
  Graphics2D g2d = currentImage.createGraphics();
  g2d.setStroke(new BasicStroke(3.0F));
  if(isPen) {
  g2d.setStroke(new BasicStroke(3f));
  if (isPen) {
    g2d.setPaint(Color.BLACK);
  }else{
  } else {
    g2d.setComposite(AlphaComposite.Clear);
    g2d.setPaint(ERASER);
  }
  g2d.drawLine(startPoint.x, startPoint.y, pt.x, pt.y);
  g2d.dispose();
  startPoint = pt;
  repaint();
}

@Override public void mousePressed(MouseEvent e) {
  startPoint = e.getPoint();
  isPen = e.getButton()==MouseEvent.BUTTON1;
  isPen = e.getButton() == MouseEvent.BUTTON1;
}
}}

**参考リンク [#rbf383fa]
-[[JPanelにマウスで自由曲線を描画>Swing/PaintPanel]]
-[[PixelGrabberで画像を配列として取得し編集、書出し>Swing/PixelGrabber]]
* 参考リンク [#reference]
- [[JPanelにマウスで自由曲線を描画>Swing/PaintPanel]]
- [[PixelGrabberで画像を配列として取得し編集、書出し>Swing/PixelGrabber]]

**コメント [#y800721a]
* コメント [#comment]
#comment
#comment