- PR -

困ってます。

1
投稿者投稿内容
コブラ
ぬし
会議室デビュー日: 2003/07/18
投稿数: 1038
お住まい・勤務地: 神奈川
投稿日時: 2003-11-16 17:57
画像のビットパターンに何らかの変更を加えて再描画する Java
Applet を作成中なのですが、配列にビットパターンを格納して
別の配列にコピーして再描画するという方法を使っています。

これが、何故か画像の一部だけしか表示しない。しかも、同じアプレ
ットをブラウザの「再読込」でリロードすると今度は問題無く表示
される。この理由が、私には解らない。是非原因と思しき部分を教えて
下さい。

[gis3.html]
<html>
<meta http-equiv="Content-Type" Content="text/html; charset=x-sjis">
<body>
<applet code=gis3.class width=1024 height=768>
</applet>
</body>
</html>

[gis3.java]
import java.applet.*;
import java.applet.Applet;
import java.awt.*;
import java.awt.image.*;
import java.awt.image.MemoryImageSource;
import java.util.*;
import java.net.*;

public class gis3 extends Applet implements Runnable
{
String gazou;

Dimension size;
MediaTracker tracker;
Image jpeg, img, dst;
Thread thread;
Graphics Scr0, Scr1;
PixelGrabber pixel, grab;
MemoryImageSource mis;
int dot[], buf[];

public void init(){
gazou = "pasta.jpg";

try {
URL imgurl = new URL(gazou);
jpeg = getImage(imgurl);
}
catch (MalformedURLException e){
jpeg = getImage(getDocumentBase(), gazou);
}

size = getImageSize(jpeg);

tracker = new MediaTracker(this);
tracker.addImage(this.jpeg, 0);

dot = new int[size.width * size.height];

mis = new MemoryImageSource(
size.width, size.height,
dot, 0, size.width);

img = createImage(mis);
dst = createImage(size.width, size.height);
Scr0 = dst.getGraphics();
Scr1 = getGraphics();
}

private Dimension getImageSize(Image image) {
int w = 0;
int h = 0;

try {
do {
w = image.getWidth(null);
h = image.getHeight(null);

Thread.currentThread().sleep(100);
} while (w < 0 || h < 0);
} catch (InterruptedException e) {
e.printStackTrace();
}

return new Dimension(w, h);
}

public void start(){
if(thread == null){
thread = new Thread(this);
thread.start();
}
}

public void paint(Graphics g){
int stat = pixel.getStatus();

if ((stat & ABORT) != 0) {
g.drawString("Image grab was aborted", 10, 100);
} else if ((stat & ALLBITS) != 0) {
g.drawString("Image grab is complete", 10, 100);
} else if ((stat & FRAMEBITS) != 0) {
g.drawString("Frame grab is complete", 10, 100);
} else if ((stat & SOMEBITS) != 0) {
g.drawString("Image grab is under way", 10, 100);
}

if ((stat & (WIDTH|ALLBITS|FRAMEBITS)) != 0) {
}

if(Scr0 != null){
try {
Scr1.drawImage(dst, 0, 0, this);
g.drawImage(img, 0, 0, this);
}
finally {
Scr0.dispose();
}
}

flush();
}

public synchronized void run(){
try {
tracker.waitForID(0);
}
catch(InterruptedException e){
e.printStackTrace();
}

pixel = new PixelGrabber(jpeg, 0, 0, size.width, size.height, dot, 0, size.width);

try {
pixel.grabPixels();
}
catch (InterruptedException e){
e.printStackTrace();
}

while(true){
dupimage();
mis.newPixels();
}
}

private void dupimage(){
buf = new int[size.width * size.height / 8];
System.arraycopy(dot, 0, buf, 0, size.width * size.height / 8);

for(int i=0; i<size.width * size.height / 8; i++){
dot[i] = buf[i];
}
}
}


画像 pasta.jpg は http://202.226.153.50/cobra/public_html/pasta.jpg
から取れます。
begood
ベテラン
会議室デビュー日: 2003/09/12
投稿数: 97
お住まい・勤務地: とうきょー
投稿日時: 2003-11-17 14:14
途中で試すのをやめてしまいましたが、見えている現象はまちまちみたいですね。私の実機では、同じ現象は毎回同じ形で見られていませんでした。参考になるかどうかは、わからず申し訳ないのですが、気になった点をいくつか記載しますので、参考になれば幸いです。

●int stat = pixel.getStatus();
の部分でNullPointerExceptionが発生してしまいました。

●どのタイミングで起こるとか、毎回起こるわけではないのですが、OutOfMemoryErrorが発生している状態で、ガーベッジコレクションが追いついていないようです。PixelGrabをうまく使用できず、オーバーフローをどこかで起こしているのかもしれません。

●スレッドを使用していますが、スレッドを使用しなくても問題は発生してしまうのかなぁ、と思われ・・・。(単純にPixelGrabを使用するだけで、試して見るのも一つの手かと思いました。)

実機によって、見える現象が違うことから、スピードとメモリに関係している部分のように思いました。もっとシンプルなコードで試してみようかと、個人的には思いましたが、時間がこれ以上なく・・・・。
Keisuke
大ベテラン
会議室デビュー日: 2003/10/24
投稿数: 105
投稿日時: 2003-11-17 14:38
このような自己中なタイトルのスレッドは無視するのが、コミュニティの利益になると思うのですが、いかがでしょうか?
たーぞう
ぬし
会議室デビュー日: 2003/08/08
投稿数: 317
お住まい・勤務地: お花畑
投稿日時: 2003-11-17 19:43
引用:
■@IT会議室のご利用についてのお願い
@IT会議室は@ITクラブ・メンバーのみなさんが、@ITの記事への感想や意見をはじめとするさまざまな情報を交換する場です。
ご利用にあたって、特に次の点についてご協力ください。お互いに気持ちよく利用できるよう、参加者一人一人の良識ある行動をお願いします。
   :
   :
ベテランのみなさんは、初心者のみなさんに対して寛容で広い心をもって接してあげてください。



というわけで悪いところは教えてあげればよいのです(自戒)。


[ メッセージ編集済み 編集者: たーぞう 編集日時 2003-11-17 19:42 ]
Keisuke
大ベテラン
会議室デビュー日: 2003/10/24
投稿数: 105
投稿日時: 2003-11-17 22:57
なるほど。

MemoryImageSource#setAnimated のような気がします。

コブラ
ぬし
会議室デビュー日: 2003/07/18
投稿数: 1038
お住まい・勤務地: 神奈川
投稿日時: 2003-11-18 02:39
いやいや、begood さん。こんなくっだらん問題に付き合って貰ろて申し訳ありませんな。
あれからソースを大幅変更して、何とか目的を達成できました。

これで、少しはまともになってませんか? > begood さん

import java.applet.*;
import java.applet.Applet;
import java.awt.*;
import java.awt.image.*;
import java.awt.image.MemoryImageSource;
import java.util.*;
import java.io.*;
import java.net.*;

public class gistemper extends Applet implements Runnable
{
String gazou;

Dimension size;
MediaTracker tracker;
Image jpeg, img, dst;
Thread thread;
Graphics Scr0, Scr1;
PixelGrabber pixel;
MemoryImageSource mis;
int dot[], buf[];

public void init(){
gazou = "pasta.jpg";

try {
URL imgurl = new URL(gazou);
jpeg = getImage(imgurl);
}
catch (MalformedURLException e){
jpeg = getImage(getDocumentBase(), gazou);
}

size = getImageSize(jpeg);

tracker = new MediaTracker(this);
tracker.addImage(this.jpeg, 0);

// dot = new int[size.width * size.height];

pixel = new PixelGrabber(jpeg, 0, 0, -1, -1, true);

try {
pixel.grabPixels();
}
catch (InterruptedException e){
e.printStackTrace();
}

dot = (int[])pixel.getPixels();

mis = new MemoryImageSource(
size.width, size.height,
dot, 0, size.width);

Scr1 = getGraphics();
}

private Dimension getImageSize(Image image) {
int w = 0;
int h = 0;

try {
do {
w = image.getWidth(null);
h = image.getHeight(null);

Thread.currentThread().sleep(100);
} while (w < 0 || h < 0);
} catch (InterruptedException e) {
e.printStackTrace();
}

return new Dimension(w, h);
}

public void start(){
if(thread == null){
thread = new Thread(this);
thread.start();
}
}

public void update(Graphics g){
paint(g);
}

public void stop(){
if(thread != null){
thread = null;
}
}

public void paint(Graphics g){
int stat = pixel.getStatus();

if ((stat & ABORT) != 0) {
g.drawString("Image grab was aborted", 10, 100);
} else if ((stat & ALLBITS) != 0) {
g.drawString("Image grab is complete", 10, 100);
} else if ((stat & FRAMEBITS) != 0) {
g.drawString("Frame grab is complete", 10, 100);
} else if ((stat & SOMEBITS) != 0) {
g.drawString("Image grab is under way", 10, 100);
}

if ((stat & (WIDTH|ALLBITS|FRAMEBITS)) != 0) {
}

dst = createImage(size.width, size.height);
Scr0 = dst.getGraphics();

dst = img;

if(dst != null){
try {
Scr1.drawImage(dst, 0, 0, this);
}
finally {
// Scr1.dispose();
}
}
}

private boolean loadImage(){
drawMessage("Loading image... " + gazou);
repaint();

try {
tracker.waitForID(0);
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}

if (tracker.isErrorID(0)) {
drawMessage("Error loading image " + gazou);
repaint();
return false;
}

return true;
}

public synchronized void run(){
if(loadImage() == false) return;

try {
tracker.waitForID(0);
}
catch(InterruptedException e){
e.printStackTrace();
}

if (tracker.isErrorAny()) {
drawMessage("ERROR: Loading images...");
return;
}

img = createImage(mis);

while(true){
dupimage();
mis.newPixels();
}
}

private void drawMessage(String message) {
Scr1.setColor(Color.black);
Scr1.fillRect(0, 0, size.width, size.height);
Scr1.setColor(Color.cyan);
Scr1.drawString(message, 10, 20);
}

private void dupimage(){
buf = new int[size.width * size.height / 8];
System.arraycopy(dot, 0, buf, 0, size.width * size.height / 8);

for(int i=0; i<size.width * size.height / 8; i++){
dot[i] = buf[i];
}
}
}
begood
ベテラン
会議室デビュー日: 2003/09/12
投稿数: 97
お住まい・勤務地: とうきょー
投稿日時: 2003-11-18 03:23
うまくいって、よかったですね。今回のコード、よくは見ていませんが、ぱっとみ、まず、前のコードのflushの部分が改善されているだけでも、よかったと・・・。前のコードそのままコンパイルしてもうごかなかったですから。

でもupdateで、paintを使用しているような感じから、うまくいっているのではと察します。
というよりも、あまり、私の意見は参考になりませんでしたね・・・。見た感じ。
コブラ
ぬし
会議室デビュー日: 2003/07/18
投稿数: 1038
お住まい・勤務地: 神奈川
投稿日時: 2003-11-18 03:37
いや、あの flush(); は偶然、、元のソースには入ってなかったのに、何を間違ったか、
どっかよそからコピー&ペーストして紛れ込んだみたいですわ。

失礼しました。
やっぱ、アドバイスあると無いとでは雲泥の差ですな(笑)
1

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