- PR -

簡単な帳票TOOLを作りたい

投稿者投稿内容
umebaind
会議室デビュー日: 2004/05/17
投稿数: 14
投稿日時: 2004-05-17 16:05
お世話になっております。梅本という者ですが
実はそろそろJAVAのグラフィックをやりたいと思いまして
その手始めに簡単な帳票TOOLを作るというのを
やりたくてあちらこちらからソースをパックって勉強しております
内容は帳票枠とデータのGIFをマージさせてJAVAの印刷機能を使用して
帳票を印刷したいのですが、うまく全体に黒色が表示出来ません(灰色になっちゃいます)。
どなたかご教授下さい。

ソースは以下の通りです。↓↓↓↓↓↓↓↓↓
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.PrintJob;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Button;
import java.awt.Frame;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Color;
public class Sample {
public static void main(String[] args) {
MyFrame frame = new MyFrame();
}
}


class MyFrame extends Frame {
public MyFrame() {
addWindowListener(new ApplicationCloser());
add(new MyCanvas());
setSize(500,500 );
show();
}
class ApplicationCloser extends WindowAdapter {
public void windowClosing(WindowEvent ev) {
System.exit(0);
}
}
}


class MyCanvas extends Canvas {
public MyCanvas() {
setBackground(Color.white);
setSize(500, 500);
}

public void paint(Graphics g) {
super.paint(g);
if (image == null) {
Image image1 = getToolkit().getImage("WAKU001.GIF");//上画像
Image image2 = getToolkit().getImage("DATA001.GIF");//下画像

MediaTracker mt = new MediaTracker(this);
mt.addImage(image1, 0);
mt.addImage(image2, 0);
try {
mt.waitForAll();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
image = blendImage(image1, image2, 0.5);//画像合成関数を呼出す

}
g.drawImage(image, 60, 60, this);//イメージを描写する。


//ここにJAVAの印刷機能を追加する//別モジュールで作成中

}

private Image blendImage(
Image imageUnder, // 下になるイメージ
Image imageOver, // 上に描画するイメージ
double tp // 上に描画するイメージの不透明度(0.0〜1.0)
) {
// パラメータのvalidチェック
if (imageUnder == null) return null;
if (imageOver == null) return imageUnder;
if (tp <= 0.0) return imageUnder;
if (tp >= 1.0) return imageOver;

// 各使用値計算
int width = imageUnder.getWidth(this);
int height = imageUnder.getHeight(this);

/// ピクセル列の取得
int[] pixelsUnder = new int[width * height];
PixelGrabber pg = new PixelGrabber(
imageUnder, 0, 0, width, height, pixelsUnder, 0, width
);
boolean ret = false;
try {
ret = pg.grabPixels();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
int[] pixelsOver = new int[width * height];
pg = new PixelGrabber(
imageOver, 0, 0, width, height, pixelsOver, 0, width
);
try {
ret = pg.grabPixels();
} catch (InterruptedException ex) {
ex.printStackTrace();
}

// 重ね合わせ
for (int i = 0; i < width * height; ++i) {
int under = pixelsUnder[i];
int over = pixelsOver[i];

// 透明なピクセルはそのまま
if ((over & 0xff000000) == 0) {
continue;
}

//あるピクセルが、ほぼ黒かを調べる方法?

// R = col & 0x00ff0000 >> 16;
// G = col & 0x0000ff00 >> 8;
// B = col & 0x000000ff;

// sr, sg, sb: 下の画像のRGB値を取り出す
double ur = (double) ((pixelsUnder[i] & 0x00ff0000) >> 16);
double ug = (double) ((pixelsUnder[i] & 0x0000ff00) >> ;
double ub = (double) (pixelsUnder[i] & 0x000000ff);


// or, og, ob: 上の画像のRGB値を取り出す
double or = (double) ((pixelsOver[i] & 0x00ff0000) >> 16);
double og = (double) ((pixelsOver[i] & 0x0000ff00) >> ;
double ob = (double) (pixelsOver[i] & 0x000000ff);




// 新しいRGB値を算出(上下の画像マージさせた値)
int nr = (int) (ur * (1.0 - tp) + or * tp);
int ng = (int) (ug * (1.0 - tp) + og * tp);
int nb = (int) (ub * (1.0 - tp) + ob * tp);

// 上の画像に下の画像のピクセル列を上書き
pixelsUnder[i] = 0xff000000 | nr << 16 | ng << 8 | nb;



}

return createImage(
new MemoryImageSource(
width, height, pixelsUnder, 0, width
)
);
}
private Image image = null;
}
umebaind
会議室デビュー日: 2004/05/17
投稿数: 14
投稿日時: 2004-05-17 16:08
度々、すいません、見れない部分がある場合 >>8 です。
Kissinger
ぬし
会議室デビュー日: 2002/04/30
投稿数: 428
お住まい・勤務地: 愛知県
投稿日時: 2004-05-18 02:44
umebaindさん、こんにちは。

tp が 0.5 で、「新しいRGB値を算出」のような演算やると
灰色になるのでしょうかね。

あと、いくつか気になること。
・この程度の処理で int → double → int は重くないですか?
・一度 Canvas に描画して配列に Grabするより、イメージとして
 処理することはできませんか?フィルタとか。
・上画像が閾値を越えたかどうかで、下画像のピクセルを置き換え
 てしまえば、今回の目的は達成されるのでは?
・paint(Graphics)の代わりに print(Graphics) で印刷するとか。
umebaind
会議室デビュー日: 2004/05/17
投稿数: 14
投稿日時: 2004-05-18 17:07
すみませんグラフィックに関しては初心者なので
もっと具体的お教え願いますか、
後、参考になるような本があれば教えて下さい。
すなめり
常連さん
会議室デビュー日: 2003/01/29
投稿数: 37
お住まい・勤務地: 横浜
投稿日時: 2004-05-18 18:56
私もグラフィックスは素人ですが、説明は出来そうです。

帳票の枠線とデータは普通は重ならないものと考えていいですよね?
すると、例えばこの演算
int nr = (int) (ur * (1.0 - tp) + or * tp);
をする場合、枠線の部分では
ur=0.0 or=255.0
のようになり、逆にデータ部分では
ur=255.0 or=0.0
のようになっているかと思います。(背景が完全に真っ白/線が真っ黒の場合)

tp=0.5を仮定すると、どちらの場合もnr=127。
g、bについても同様ですので、出力結果としては枠線もデータも灰色にしかならない、
ということです。

重ね合わせの場合は、透過する色を決めて、上の画像のあるピクセルが透過する色ならば
下の画像の色を採用する、とするとよいのではないか、と思います。
umebaind
会議室デビュー日: 2004/05/17
投稿数: 14
投稿日時: 2004-05-19 09:07
ありがとうございます。
なんとかがんばってみます
これからもよろしくお願いします。
umebaind
会議室デビュー日: 2004/05/17
投稿数: 14
投稿日時: 2004-05-19 14:21
簡単な帳票TOOL
お世話になっております。
ご指摘のあったDOUBLE⇔INT変換(やはり重かった)
灰色の中間色の対応したらうまく表示出来ました。
あとカウンタを付加してPAGE数を追加したいのですが
TXTをIMAGEに変換してADDすればうまくいきますか?
又、TXTをIMAGEに変換する方法とIMAGEにADDする方法をどなたか
ご教授下さい。よろしくお願いします。

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.PrintJob;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Button;
import java.awt.Frame;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Color;

public class Sample {
static void main(String[] args) {

MyFrame frame = new MyFrame();
}
}
class MyFrame extends Frame {
public MyFrame() {
addWindowListener(new ApplicationCloser());
add(new MyCanvas());
setSize(500,500 );
show();
}
class ApplicationCloser extends WindowAdapter {
public void windowClosing(WindowEvent ev) {
System.exit(0);
}
}
}


class MyCanvas extends Canvas {
public MyCanvas() {
setBackground(Color.white);
setSize(500, 500);
}

public void paint(Graphics g) {
super.paint(g);
if (image == null) {
Image image1 = getToolkit().getImage("WAKU001.GIF");//上画像
Image image2 = getToolkit().getImage("DATA001.GIF");//下画像

MediaTracker mt = new MediaTracker(this);
mt.addImage(image1, 0);
mt.addImage(image2, 0);
try {
mt.waitForAll();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
image = blendImage(image1, image2, 0.5) ;//画像合成関数を呼出す

}

g.drawImage(image , 60, 60, this);//イメージを描写する。


//ここにJAVAの印刷機能を追加する//別モジュールで作成中

}
//JDK1.4からVolatileImage(通常より5倍早い......にいずれ変更する)
private Image blendImage(Image imageUnder, // 下になるイメージ
Image imageOver, // 上に描画するイメージ
double colorpi // 上に描画するイメージの不透明度(0.0〜1.0)
)
{
// パラメータのvalidチェック
if (imageUnder == null) return null;
if (imageOver == null) return imageUnder;
if (colorpi <= 0.0) return imageUnder;
if (colorpi >= 1.0) return imageOver;

// 各使用値計算
int width = imageUnder.getWidth(this);
int height = imageUnder.getHeight(this);

/// ピクセル列の取得
int[] pixelsShita = new int[width * height];
PixelGrabber pg = new PixelGrabber(
imageUnder, 0, 0, width, height, pixelsShita, 0, width
);
boolean ret = false;
try {
ret = pg.grabPixels();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
int[] pixelsUe = new int[width * height];
pg = new PixelGrabber(
imageOver, 0, 0, width, height, pixelsUe, 0, width
);
try {
ret = pg.grabPixels();
} catch (InterruptedException ex) {
ex.printStackTrace();
}

// 重ね合わせ
for (int i = 0; i < width * height; ++i) {
int under = pixelsShita[i];
int over = pixelsUe[i];

// 透明なピクセルはそのまま
if ((over & 0xff000000) == 0) {
continue;
}

//あるピクセルが、ほぼ黒かを調べる方法?

// R = col & 0x00ff0000 >> 16;
// G = col & 0x0000ff00 >> 8;
// B = col & 0x000000ff;

// sr, sg, sb: 下の画像のRGB値を取り出す
int ur = (int) ((pixelsShita[i] & 0x00ff0000) >> 16);
int ug = (int) ((pixelsShita[i] & 0x0000ff00) >> 8 );
int ub = (int) (pixelsShita[i] & 0x000000ff);

// or, og, ob: 上の画像のRGB値を取り出す
int or = (int) ((pixelsUe[i] & 0x00ff0000) >> 16);
int og = (int) ((pixelsUe[i] & 0x0000ff00) >> ;
int ob = (int) (pixelsUe[i] & 0x000000ff);

int nr=0;
int ng=0;
int nb=0;

// 新しいRGB値を算出(上下の画像マージさせた値)
// int nr = (int) (ur * (1.0 - colorpi) + or * colorpi);
// int ng = (int) (ug * (1.0 - colorpi) + og * colorpi);
// int nb = (int) (ub * (1.0 - colorpi) + ob * colorpi);

//*******************************************************************
//* 帳票生成
//*******************************************************************
//* 内容:
//* 帳票枠(FORM)のイメージと帳票DATAをマージさせて
//* 帳票を作りだ
//*

//RED :新しいRGB値を算出(上下の画像マージさせた値)
nr = (int) (ur * (1.0 - colorpi) + or * colorpi);

if(nr==127){ nr=0; }//中間色であれば強制的に黒にする

//GREEN:新しいRGB値を算出(上下の画像マージさせた値)
ng = (int) (ug * (1.0 - colorpi) + og * colorpi);

if(ng==127){ ng=0; }//中間色であれば強制的に黒にする

//BLUE :新しいRGB値を算出(上下の画像マージさせた値)
nb = (int) (ub * (1.0 - colorpi) + ob * colorpi);

if(nb==127){ nb=0; }//中間色であれば強制的に黒にする

//処理後のピクセルの情報を元に戻す
pixelsShita[i] = 0xff000000 | nr << 16 | ng << 8 | nb;

}

//MemoryImageSource(作成する画像の幅,作成する画像の高さ,元になる配列,配列の先頭位置,1行あたりのピクセル数 );

// 上の画像に下の画像のピクセル列を上書き
return createImage(new MemoryImageSource(width, height, pixelsShita,0, width ));
}
private Image image = null;
}







umebaind
会議室デビュー日: 2004/05/17
投稿数: 14
投稿日時: 2004-05-19 16:22
簡単な帳票TOOLについて
度々しつこくてすみません。

カウンタを付加してPAGE数を追加したいのですが
TXTをIMAGEに変換してADDすればうまくいきますか?
又、TXTをIMAGEに変換する方法とIMAGEにADDする方法をどなたか
ご教授下さい。よろしくお願いします。

スキルアップ/キャリアアップ(JOB@IT)