静止画像上に表示する線の改良方法とは?

このQ&Aのポイント
  • 静止画像(img)の上に表示している線を、静止画像の輝度情報が半分(50%)になっている線(画質が劣化している線)を表示させるように改良したい。
  • 改良方法は、setColorの部分を変える。
  • プログラムは、画面上に表示している静止画像(img)の上に、ランダムに黒色のライン(buffer)を数本表示するもの。
回答を見る
  • ベストアンサー

改良したいのですが

画面上に表示している静止画像(img)の上に、ランダムに黒色のライン(buffer)を数本表示するというプログラムを作成しました。次はそのプログラムの一部なのですが、静止画像の上に表示している線を、黒色ではなく、静止画像の輝度情報が半分(50%)になっている線(画質が劣化している線)を表示させるように改良したいのですが、どこを変えたらいいのか、どのように変えたらいいのかわかりません。わかる方いましたら、アドバイス等お願いします。多分setColorの部分を変えると思うのですが・・・(^^; public void paint(Graphics g){ int w,h; w = (int)getSize().width; h = (int)getSize().height; bufferGraphics.drawImage(img,0,0,this); bufferGraphics.setColor(Color.black); //処理を10回繰り返す for(int j=0; j<10; j++){ //2から1002の中で乱数を1つranに取得 int ran = (int)(Math.random() * 1000)+2; for(int i=0;i<h;i+=ran){ //ranの値にしたがって画面上にラインを表示 bufferGraphics.drawLine(0,i,w,i); } g.drawImage(buffer,0,0,null); } } public void update(Graphics g){ paint(g); } public void run(){ while( true ){ try{ Thread.sleep(10); } catch(InterruptedException e){ } } } public void start(){ thread = new Thread(this); thread.start(); } }

  • mos21
  • お礼率46% (128/273)
  • Java
  • 回答数3
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • liar_adan
  • ベストアンサー率48% (730/1515)
回答No.3

import java.applet.*; import java.awt.*; public class Ap extends Applet implements Runnable{ Image img; Image buffer; Graphics bufferGraphics; Thread thread; public void init(){ img = getImage(getDocumentBase(), "abc.jpg"); buffer = createImage(100, 100); bufferGraphics = buffer.getGraphics(); bufferGraphics.drawImage(img, 0, 0, this); } うちでもいろいろやってみました。 問題のプログラムの前半を↑のようにして(クラス名は適当につけました)、 アプレットとして実行してみるといちおう動作しました。 細かい点として、ソースにあった > g.drawImage(buffer,0,0,null); は > g.drawImage(buffer,0,0,this); の方がいいかもしれません。 前回の(0, 0, 0, 128)という色情報は、 前から順に赤、緑、青、アルファ値を0~256の範囲で指定しています。 アルファ値というのは透明度です。128ぐらいにすると 下の色が半分透けて見えます。 これはfloatで指定することも可能です。 その場合、 new Color(0.0, 0.0, 0.0, 0.5); のようになります。 詳しくはAPIドキュメント(持ってますよね?)の Colorのところを見てください。 いろいろやってみて、プログラムにいくつか疑問が生じました。 後半のスレッド関係のところ、このままではあまり意味が無いようですが、 これは何を意図したものでしょうか? また、このままだと、paint()は画面が書き換えられるときだけしか意味を持ちません。 つまり、「他のウィンドウの下になって、また出てきた」「最小化されて、また最大化された」 などのときのみです。 これは何を意図しているのでしょうか? 想像ですが、TV画像がぶれたような効果? その場合、 > Thread.sleep(10); の後にrepaint();と入れるとそうなりますが…。

mos21
質問者

お礼

ありがとうございました。これは、ネット上に公開されている画像を、画像を更新するたびに黒色のラインがランダムに表示されるというプログラムです。このラインを輝度が50%のラインにしてrepaint()して、別々のラインが引かれた画像を順次表示することによりネット上で普通の画像が公開されているように見せるものです。これによりprintscreenキーでコピーされた画像ではラインがばらばらな画像が取得できるため不正コピーを防げるというものです。長くてわかりずらいですかね(^^;

その他の回答 (2)

  • liar_adan
  • ベストアンサー率48% (730/1515)
回答No.2

>に変えてみたところ画像は表示されませんでした(^^; あれ、おかしいな。できるはずなんだけど。 このbufferGraphicsはどこから取ったGraphicsでしょうか? ダブルバッファリング用に作ったImageのGraphics打と思いますが、 それはコンポーネントのcreateImage()で作ったものでしょうか? それとも、BufferedImageクラスのイメージでしょうか? BufferedImageのイメージなら、それを生成するとき、 new BufferedImage(x, y, BufferedImage.TYPE_INT_RGB); のように作ったでしょうか。それならば new BufferedImage(x, y, BufferedImage.TYPE_INT_ARGB); に変えてください。TYPE_INT_RGBはアルファ値を保存しないものです。 TYPE_INT_ARGBだとアルファ値が使えるイメージになります。 原因がそれで無い場合、ちょっとわかりませんが、 イメージの素性について補足ください。

mos21
質問者

補足

遅くなりました(>_<) paint()の前のinit()の中でcreateImage()を用いているので、createImage()で作ったものだと思います。以前回答いただいた(0,0,0,128)という所がよくわかりませんでした。これはどのような色情報を意味しているのですか?それとも色情報ではないですか?

  • liar_adan
  • ベストアンサー率48% (730/1515)
回答No.1

色を作ります。 黒とか赤とかのよく使われる色は、Colorクラスに用意されていますが、 それ以外のものはColorオブジェクトを作ります。 (コンストラクタの詳細についてはAPIドキュメントを見てください) Color c = new Color(0, 0, 0, 128); bufferGraphics.setColor(c); でできます。 bufferGraphics.setColor(new Color(0, 0, 0, 128)); でもいいかな。

mos21
質問者

お礼

bufferGraphics.setColor(Color.black); の部分をbufferGraphics.setColor(new Color(0, 0, 0, 128));に変えてみたところ画像は表示されませんでした(^^; int r = (int)(pixels[i]&0x00ff0000); if (r!=0x00000000){r = ((int)((pixels[i]&0x00ff0000)*0.5)&0x00ff0000);} int g = (int)(pixels[i]&0x0000ff00); if (g!=0x00000000){g = ((int)((pixels[i]&0x0000ff00)*0.5)&0x0000ff00);} int b = (int)(pixels[i]&0x000000ff); if (b!=0x00000000){b = ((int)((pixels[i]&0x000000ff)*0.5)&0x000000ff);}のようにr.g.bに色情報を与えて、何かできないですかね?(pixelsには静止画像データが入っています。)

関連するQ&A

  • 意味がわかりません。

    2から902の中で乱数を10個ranに格納し、それをi=0からi+=ran表示するというプログラムを作成しました。下のプログラムはその1部なのですが、意味のわからない部分があり困っています。ranには得られた10個の乱数のうちの1つの数字が格納されますよね。10個取得したとはどういった処理がされるのでしょうか? public void paint(Graphics g){ int w,h; w = (int)getSize().width; h = (int)getSize().height; bufferGraphics.drawImage(image,0,0,this); bufferGraphics.setColor(Color.black); int rand; //2から902の中で乱数を10個ranに格納 for(int j=0; j<10; j++){ int ran = (int)(Math.random() * 1000)+2; for(int i=0;i<h;i+=ran){ bufferGraphics.drawLine(0,i,w,i); } g.drawImage(buffer,0,0,null); } }

    • ベストアンサー
    • Java
  • 意味がわかりません

    この部分の意味がわからなくて困っています。わかる方いましたら解説をお願いします。m(_ _)m public void paint(Graphics g){ int w,h; w = (int)getSize().width; h = (int)getSize().height; if(f==0){ bufferGraphics.drawImage(image,0,0,this); bufferGraphics.setColor(Color.white); for(int i=0;i<h;i+=2){ bufferGraphics.drawLine(0,i,w,i); } g.drawImage(buffer,0,0,null); f = 1; } else if(f==1) { bufferGraphics.drawImage(image,0,0,this); bufferGraphics.setColor(Color.white); for(int i=1;i<h;i+=2){ bufferGraphics.drawLine(0,i,w,i); } g.drawImage(buffer,0,0,null); f = 0; } }

    • ベストアンサー
    • Java
  • コンパイルできません

    imgにオリジナルの画像データを格納して、それを配列pixelsに格納した後、またpixelsをimg2等に格納してimg2を画面上に表示する。というものを作りたいのですが、コンパイルできなくて困っています。次はプログラムの一部です。pixelsに格納するところでエラーが出てしまいます。エラー内容は シンボルを解釈処理できません。 シンボル: クラス PixelGrabber 位置 : na3 の クラス PixelGrabber pg = new PixelGrabber(img,0,0,w,h,pixels,0,scan) と表示されます。 わかるかたいましたらお願いします。 img = Toolkit.getDefaultToolkit().createImage(imagedata); int w,h; w = (int)getSize().width; h = (int)getSize().height; buffer = this.createImage(w,h); bufferGraphics = buffer.getGraphics(); } public void paint(Graphics g){ int w,h; w = (int)getSize().width; h = (int)getSize().height; int[] pixels = new int[w * h]; int scan = w; int offset = 0; PixelGrabber pg = new PixelGrabber(img,0,0,w,h,pixels,0,scan); try{ pg.grabPixels(); } catch(InterruptedException e){ ; } bufferGraphics.drawImage(img,0,0,this); bufferGraphics.setColor(Color.black); //処理を10回繰り返す for(int j=0; j<10; j++){ //2から1002の中で乱数を1つranに取得 int ran = (int)(Math.random() * 1000)+2; for(int i=0;i<h;i+=ran){ //ranの値にしたがって画面上にラインを表示 bufferGraphics.drawLine(0,i,w,i); } g.drawImage(buffer,0,0,null); } }

    • ベストアンサー
    • Java
  • Appletのrepaint()が動作しません

    import java.applet.*; import java.awt.*; /*<applet code="zxy" width="1000" height="1000"></applet>*/ class Object extends Applet { protected int x; /* オブジェクトのx座標 */ protected int y; /* オブジェクトのy座標 */ protected int width; protected int height; Image buffer; Graphics buffer_g; Dimension d = getSize(); public Object() { x = 0; y = 0; width = 0; height = 0; } } /* 楕円クラス */ class Oval extends Object implements Runnable { public Oval() { width = (int)(Math.random() * 56 + 10); height = (int)(Math.random() * 56 + 10); } public void run() { while( true ){ try{ repaint(); Thread.sleep(50); } catch( Exception e ){} } } public void paint( Graphics g ) { if( buffer_g == null ) buffer_g = buffer.getGraphics(); Dimension d = getSize(); buffer_g.setColor( Color.white ); buffer_g.fillRect( 0, 0, d.width, d.height ); buffer_g.setColor( Color.black ); buffer_g.drawOval( x, y, width, height ); x += (int)(Math.random() * 10); y += (int)(Math.random() * 10); g.drawImage( buffer, 0, 0, this ); } } public class A extends Applet { Image buffer; Graphics buffer_g; Oval ov1 = new Oval(); Thread thOv1 = new Thread( ov1 ); public void start() { thOv1.start(); Dimension d = getSize(); buffer = createImage( d.width, d.height ); } } 上記プログラムを実行しても、paint()の中が実行されずにtryブロックを繰り返すだけになってしまいます。paint()を実行するにはどうすればいいでしょうか?

  • public void paint(Graphics g){

    public void paint(Graphics g){ g.setColor(new Color(ci, ci, ci)); g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(Color.WHITE); g.drawString("Canvas表示", 20, 20); g.drawImage(image, x1, y1, this); g.drawImage(image1, x2, y2, this); } public void update(Graphics g){ paint(g); } public void run(){         //while(true)で永久ループ //imageの座標を変更する処理         //repaint();     } スレッドを使ってイメージの座標を変更し、イメージが動くプログラムを作りました。 これだと滑らかに動かないからpaintメソッドをもうひとつ作って 処理するpaintと描画するpaintとにわけたらいいと言われました。 ですがやりかたがわからないので教えてください。

  • シンボルが見つけられません。8個のエラー。

    シンボルが見つけられません。 8個のエラーメッセージがでました。 何度も打ち直しましたが、これ以上減りません。 ドコが誤ってますか? ご多忙中申し訳ありません。 ご回答の程、宜しくお願い申し上げます。 import java.applet.*; import java.awt.*; import java.util.*; public class DigitalClock extends Applet implements Runnable { Thread thread = null; Image Digit[ ] = new Image[11]; int DigitWidth, DegitHeight; Image WorkImage; Graphics WorkGraphics; int AppletWidth, AppletHight; //初期化処理---------------------------------------------------- public void init() { AppletWidth = getSize().width; AppletHight = getSize().height; WorkImage = createImage(AppletWidth, AppletHight); WorkGraphics = WorkImage.getGraphics(); MediaTracker mediaTracker = new MediaTracker(this); for(int i = 0; i < 11;i++) { Digit[i] = getImage(getCodeBase(),"Image/" + i +".gif"); mediatracker.addImage(Digit[i],1); } try{ mediatracker.waitForID(1); } catch (InterruptedException e) { showStatus(""+e); } DigitWidth = Degit[0].getWidth(this); DegitHeight = Digit[0].getHeight(this); } //アプレット開始------------------------------------------------------- public void start() { thread = new Thread(this); thread.start(); } //描画処理-------------------------------------------------------------- public void paint(Graphics g) { g.drawImage(WorkImage, 0, 0, this); } //スレッド処理------------------------------------------------------------ public void run(){ while (thread != null) { DispTime(); repaint(); try { thread.sleep(100); } catch(InterruptedException e) { showStatus(""+e); } } } //描画更新処理再定義---------------------------------------------------------- public void update(Graphics g) { paint(g); } //時間描画-------------------------------------------------------------------- void DispTime() { //カレンダーオブジェクト作成 Calendar date = Calendar.getInstance(TimeZone.getTimezone("JST")); int hour = date.get(Calender.HOUR); int minute = date.get(Calender.MINUTE); int second = date.get(Calendar.SECOND); //作業グラフィックに描画 WorkGraphics.setcolor(color.white); WorkGraphics.fillRect(0, 0, DigitWidth*8, DigitHight); int h1 = hour / 10, h2 = hour % 10; WorkGraphics.drawImage(Digit[h1], 0,0, this); WorkGraphics.drawImage(Digit[h2], DigitWidth*1, 0, this); WorkGraphics.drawImage(Digit[10], DigitWidth*2, 0, this); int m1 = minute / 10, m2 = minute % 10; WorkGraphics.drawImage(Digit[m1], DigitWidth*3, 0, this); WorkGraphics.drawImage(Digit[m2], DigitWidth*4, 0, this); WorkGraphics.drawImage(Digit[10], DigitWidth*5, 0, this); int s1 = second / 10, s2 = second % 10; WorkGraphics.drawImage(Digit[s1], DigitWidth*6, 0, this); WorkGraphics.drawImage(Digit[s2], DigitWidth*7, 0, this); } //アプレット停止 public void stop() { thread = null; } }

    • ベストアンサー
    • Java
  • ウインドウを大きくしてもボールの動きが変わらない

     今晩は、java初心者です。  宜しくお願い致します。  "ComponentListener"でウインドウを"componentResized"してもボールの動く範囲 は変わりません、何故でしょうか。    "componentResized"では確かに"Resized"されたウインドウの大きさをとっていますが、 何故かボールの動きには反映されません。  宜しくお願いします。 ======================================================================================== public class Ball2 extends Applet implements Runnable , ComponentListener { public static final long serialVersionUID = 1L ; int width , height ; Thread thread ; boolean  LoopFlag = false  ; int x = 30 , y = 100 ; Image  offScreen ; Graphics screen ; int vx = 2 , vy = 2 ; public void init() { width = getSize().width ; height = getSize().height ; thread = new Thread( this ); thread.start(); offScreen = createImage( width, height ) ; screen = offScreen.getGraphics() ; addComponentListener(this) ; } public void componentResized( ComponentEvent e ) { width = getSize().width ; height = getSize().height ; } public void run() { while( LoopFlag == false ) { move() ; repaint() ; try { Thread.sleep( 10 ) ; } catch ( InterruptedException e ) {} } } private void move() { if( x >= width - 50 ) { vx =- vx ; } if( y >= height - 50 ) { vy =- vy ; } if( x < 0 ) { vx =- vx ; } if( y < 0 ) { vy =-vy ; } x += vx; y += vy; } public void update( Graphics g) { paint(g) ; } public void paint( Graphics g) { screen.clearRect( 0 , 0 , width , height ) ; screen.setColor( Color.blue ) ; screen.fillOval( x , y , 50 , 50 ) ; g.drawImage( offScreen , 0 , 0 , this ) ; } public void destroy() { LoopFlag = true ; } public void componentHidden( ComponentEvent e ){} public void componentMoved( ComponentEvent e ){} public void componentShown( ComponentEvent e ){} }

    • ベストアンサー
    • Java
  • androidの円(circle)を連続で出したい

    android初心者です。 androidの円(circle)を連続で出したいソースを作成していますがうまくいきません。 現在のソースではランダムで座標を取得することは出来ますが表示されません。 for文for(i=0;i<100;i++)で作成してみましたが、100回終わるまで円が表示されません。 以下が自分で作成してみたソースです。 どなたか詳しい方教えてください。 public class Balltataki extends Activity { int ran_width; int ran_height; Paint paint; boolean running=true; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); getWindow().setFormat(PixelFormat.TRANSLUCENT); setContentView(new BallView(this)); class BallView extends View { int flag=1; public BallView(Context context) { super(context); } @Override protected void onDraw(Canvas canvas) { while(running==true){ ran_width = (int)(Math.random()*getWidth()); ran_height = (int)(Math.random()*getHeight()); Log.i("tag","ran_w:"+ran_width); Log.i("tag","ran_h:"+ran_height); paint=new Paint(); paint.setAntiAlias(true); paint.setStrokeWidth(1); paint.setStyle(Paint.Style.FILL); paint.setColor(Color.argb(255, 255, 255, 255)); canvas.drawCircle(ran_width,ran_height,60,paint); try { Thread.sleep(100); } catch (Exception e) {} } } } }

  • コンパイルできません

    次のようなプログラムを作成しましたのですが、コンパイルできなくて困っています。img2,img3,img4にはそれぞれ画像データが入っていて、それを順番に表示させながらループさせたいのですけど(^^; public void update(Graphics g) {paint(g);} public void paint(Graphics g){ for(int state=0; state < 3; state++); { switch(state){ case 0:  buffer=img2; break; case 1:  buffer=img3; break; case 2:  buffer=img4; break; } } g.drawImage(buffer,0,0,null); } switch(state){の部分で「シンボルを解釈処理できません。シンボル: 変数 state」というエラーが出てしまいます。どこが間違っているかわかりません。お願いします。

    • ベストアンサー
    • Java
  • デジタル時計を表示するには?

    いつもお世話になりありがとうございます。 標記の件。 エディターはVS codeを使っております。 コードは下記です。 import java.applet.*; // Applet import java.awt.*; // Graphics, Image, Color, MediaTracker import java.util.*; // Calendar, TimeZone public class DigitalClock extends Applet implements Runnable { Thread thread = null; Image Digit[ ] = new Image[11]; // 画像データ(0~9,:) int DigitWidth, DigitHeight; // 画像データの幅と高さ Image WorkImage; // 作業用イメージ Graphics WorkGraphics; // 作業用グラフィックス int AppletWidth, AppletHeight; // アプレットの幅と高さ // 初期化処理 ----------------------------------------------------------------------- public void init( ) { AppletWidth = getSize( ).width; // アプレットの幅と高さ AppletHeight = getSize( ).height; WorkImage = createImage(AppletWidth, AppletHeight); // 作業用イメージ作成 WorkGraphics = WorkImage.getGraphics( ); // 作業用グラフィックス取得 MediaTracker mediatracker = new MediaTracker(this); // メディアトラッカー生成 for(int i = 0; i < 11; i++) { // 画像データを入力 Digit[i] = getImage(getCodeBase( ), "image/" + i + ".gif"); mediatracker.addImage(Digit[i], 1); // メディアトラッカーに入力画像を設定 } try { mediatracker.waitForID(1); // 画像入力が完了するまで待つ } catch (InterruptedException e) { // waitForIDに対する例外処理 showStatus(" "+e); } DigitWidth = Digit[0].getWidth(this); // 画像サイズ DigitHeight = Digit[0].getHeight(this); } // アプレット開始 ------------------------------------------------------------------- public void start( ) { thread = new Thread(this); // スレッド生成 thread.start( ); // スレッドスタート } // 描画処理 ------------------------------------------------------------------------- public void paint(Graphics g) { g.drawImage(WorkImage, 0, 0, this); // 作業イメージをアプレットに描画 } // スレッド実行 --------------------------------------------------------------------- public void run( ) { while (thread != null) { // スレッドが存在している間 DispTime( ); // 時刻描画 repaint( ); // 再描画 try{ thread.sleep(100); // スリープ } catch(InterruptedException e) { // 他のスレッドの割り込み例外処理 showStatus(" "+e); } } } // 描画更新処理再定義 --------------------------------------------------------------- public void update(Graphics g) { // デフォルトのupdateを再定義 paint(g); // 背景色画面クリア削除,paintのみ } // 時間描画 ------------------------------------------------------------------------- void DispTime( ) { // カレンダーオブジェクト作成 Calendar date = Calendar.getInstance(TimeZone.getTimeZone("JST")); int hour = date.get(Calendar.HOUR); // 現在時刻の時間取得 int minute = date.get(Calendar.MINUTE); // 現在時刻の分取得 int second = date.get(Calendar.SECOND); // 現在時刻の秒取得 // 作業グラフィックに描画 WorkGraphics.setColor(Color.white); WorkGraphics.fillRect(0, 0, DigitWidth*8, DigitHeight); int h1 = hour / 10, // 時間の10の桁 h2 = hour % 10; // 時間の1の桁 WorkGraphics.drawImage(Digit[h1], 0, 0, this); WorkGraphics.drawImage(Digit[h2], DigitWidth*1, 0, this); WorkGraphics.drawImage(Digit[10], DigitWidth*2, 0, this); int m1 = minute / 10, // 分の10の桁 m2 = minute % 10; // 分の1の桁 WorkGraphics.drawImage(Digit[m1], DigitWidth*3, 0, this); WorkGraphics.drawImage(Digit[m2], DigitWidth*4, 0, this); WorkGraphics.drawImage(Digit[10], DigitWidth*5, 0, this); int s1 = second / 10, // 秒の10の桁 s2 = second % 10; // 秒の1の桁 WorkGraphics.drawImage(Digit[s1], DigitWidth*6, 0, this); WorkGraphics.drawImage(Digit[s2], DigitWidth*7, 0, this); } // アプレット停止 ------------------------------------------------------------------- public void stop( ) { thread = null; // スレッドを無効 } } ご回答のほど宜しくお願い申し上げます。

    • ベストアンサー
    • Java

専門家に質問してみよう