• 締切済み

【JAVA】画像のサイズを大きく変化させない方法

行き詰ったので質問させてください。 TIFファイル画像があり、それに文字を組み込みたいため以下のようなソースを書きました。 BufferedImage image = null; image = ImageIO.read(file); Graphics graphics = image.createGraphics(); graphics.setColor(Color.RED); graphics.setFont(new Font("MSゴシック", Font.BOLD, 100)); graphics.drowString("TEST",100,200); ImageIO.write(image,"tif", new File(file.toString())); 画像には「TEST」の文字が組み込まれたのですが、ファイルサイズが 50kbから500kb(約10倍)になり、サイズ変化させたくなかったため対策 を練ってます。 JPEGEncoderParamクラスなどを利用し、setQualityメソッドで画質を変えた りもしたのですが、それでも元画像の7倍ほどになり、他の方法を取らざるを得ません。 画像のサイズは元サイズとほぼ変わらないような方法で、プログラムを組むことは できますでしょうか。ちなみに画像は白黒です。 以上、お力添えください。

  • Java
  • 回答数2
  • ありがとう数1

みんなの回答

  • mpro-gram
  • ベストアンサー率74% (170/228)
回答No.2

tiffの扱いはあんまり知らないけど、wikiによれば、「TIFFファイルでは、画像データの先頭部分に記録形式についての属性情報が記録される。」なので、実際の画像の形式が何なのかによって、ファイルサイズは大きく変わるようです。 jpegやpng は2色しか使って無くても、1ドットにつき16から24ビット使うので、たとえ圧縮してもファイルサイズは大きくなります。 で、2色しかないなら、ビットマップの白黒モード+圧縮で保存するのがもっともサイズが小さいと思うけど、java でその書き込みができたか不明。 >JPEGEncoderParamクラスなどを利用し、 これだとたぶんtiffの中身もjpegになるし、tiff用の情報付加により、通常のjpeg保存よりもさらに大きいファイルになるようです。 以下のページをさらっと読んだかぎりでは、内部画像をBufferedImage.TYPE_BYTE_BINARY で2値画像で保持してれば、いけるかな??? http://hondou.homedns.org/pukiwiki/pukiwiki.php?JavaSE%20ImageIO%20%A4%C7%20tiff%20%B2%E8%C1%FC%A4%F2%B0%B7%A4%A6 無理なら、windowsのペイントで作っちゃうのが早そうな気がする。 ペイントで作るときも、先に一旦モノクロビットマップで保存しておいてから、保存時ファイル形式をtiffに変更して再保存としないと、tiffの中身は、多色ビットマップで保存されちゃったり、gifやpngだったりしてファイルサイズは大きくなるので要注意。

  • teketon
  • ベストアンサー率65% (141/215)
回答No.1

Javaでは標準でTIFF形式のファイル書き込みはできなかったと記憶しています。 TIFと言う拡張子の別のファイル形式になっていませんか?

samkunojisan
質問者

お礼

ありがとうございました

samkunojisan
質問者

補足

回答ありがとうございます。 TIFへの書き込み及び読み込みはImageIO.getReaderFormatNamesメソッドの結果から対応可能となっております。 graphicsクラスを用いない別の方法でも構わないので、文字を画像に埋め込んで、それを元のサイズに近い状態で画像を保存する方法について、もしご存知でしたらご教示ください。よろしくお願いします。

関連するQ&A

  • 【Java】読み込んだ画像の色がおかしい

    Java の BufferedImage を使ってJPGファイルを読み込むと、 ファイルによっては色が写真のネガのように変わってしまうことがあります。 本当は読み込んだJPGファイルを編集したいのですが、 次のように読み込んで出力するだけで、この現象が起きます。 String orgImageFile = "test.jpg"; // 読み込むファイル String outputFile = "output.jpg"; // 出力するファイル BufferedImage orgImage = ImageIO.read(orgImageFile); ImageIO.write(orgImage, "jpg", new File(outputFile)); なにか解決策はございませんでしょうか。 よろしくお願い致します。

    • ベストアンサー
    • Java
  • 任意の文字列をJAVAで画像化

    表題にある通り任意の文字列をJAVAで画像化したいと思い 下記サンプルを検索して見つけたのですが作成される画像は 真っ白な画像で文字列は表示されませんでした。 任意の文字列を画像として出力するにはどうすればよいでしょうか。 import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; public class Test5 { public static void main(String[] args) { String str = "abc123"; new Test5().Create(str); System.out.println(str); } public void Create(String str) { int w=60; int h=17; try { //受け取った文字列を画像化 BufferedImage image=new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB); Graphics2D g2d=image.createGraphics(); g2d.setBackground(Color.WHITE); g2d.clearRect(0,0,w,h); g2d.setColor(Color.BLACK); g2d.drawString(str,0,0); ImageIO.write(image, "JPEG", new File("c:\\test.jpg")); } catch(Exception e) { e.printStackTrace(); } } }

    • ベストアンサー
    • Java
  • java 画像変換 加工 サイズ変更

    OracleDBからBLOB型の画像データを取得しています。 本来必要のなかった処理なのですが、DBに入っている画像のデータがおかしいらしく、ピクセルとdpiの値を変更しなければなりません。 いろいろと調べてやってみようと思ったのですが、いきづまってしまいました(><) みなさんの力をお貸しください。 内容は、 ・一度DBからそのまま画像を抽出し、ファイルを作成 ・作成したファイルをもう一度BufferedImageに取り込み、サイズ変更処理開始 となっています。 しかし、BufferedImageに取り込む際に、nullが帰ってきてしまい、以降の処理ができません・・・。 また、下記処理はすべてjpgで行っていますが、本当はTiffファイルを作りたいのです。 ImageIOクラスは標準ではTiffは対応していないようなのですが、実際に下記ソースの"jpg"を"tif"に変更しても問題はないのでしょうか? 質問が煩雑で申し訳ないですが、よろしくお願いいたします。 以下ソース抜粋です。 ---------------------------------------------------------------- ImageOutNum = (String)rs.get("IMAGEGRPNO"+i)+"_"+(String)rs.get("IMAGENO"+i); // イメージファイルを作成する。 File imagef = new File(outPath2); if(!(imagef.exists()))imagef.mkdirs(); InputStream inImage = (InputStream)rs.get("IMAGEFILE"+i); if (inImage != null) { FileOutputStream outImage = new FileOutputStream(outPath2 + ImageOutNum + ".jpg"); //画像書き込み int j; while ((j = inImage.read()) != -1) { outImage.write(j); } // 解放 outImage.close(); //イメージ変更処理 InputStream orgImageFile = null; orgImageFile = new FileInputStream(outPath2 + ImageOutNum + ".jpg"); BufferedImage orgImage = ImageIO.read(orgImageFile);//ここでorgImageにnullが返されてしまいます。 int width = 640; int height = (int)(((double)width / orgImage.getWidth()) * (double)orgImage.getHeight()); BufferedImage resizeImage = new BufferedImage(width, height, orgImage.getType()); // ここからリサイズ処理 AffineTransformOp ato = null; ato = new AffineTransformOp( AffineTransform.getScaleInstance((double)width / orgImage.getWidth(),(double) height / orgImage.getHeight()),null); ato.filter(orgImage, resizeImage); // ここまでリサイズ処理 ImageOutputStream imageStream = ImageIO.createImageOutputStream(new File(outPath2 + ImageOutNum + ".jpg")); ImageWriter writer = null; Iterator it = (Iterator) ImageIO.getImageWritersByFormatName("jpg"); writer = (ImageWriter) it.next(); writer.setOutput(imageStream); JPEGImageWriteParam jpgWriter = new JPEGImageWriteParam(Locale.getDefault()); jpgWriter.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); jpgWriter.setCompressionQuality(1f); writer.write(null, new IIOImage(resizeImage, null, null), jpgWriter); imageStream.flush(); writer.dispose(); imageStream.close();

  • 画像の重ね合わせがうまくできません・・

    はじめまして。 画像を重ね合わせるプログラムを作成したいのですが、 期待通りにならないため悩んでおります。 Aという画像を下地に、Bという画像の特定RGBのドットを透過させて合成した画像を作りたいのですが、 どうもうまくいかず、半透明な絵ができてしまいます。 (Aがうっすらと見え、Bが重なるかんじ) 合成部分のコーディングは以下です。 AlphaCompositeの使い方が間違っているのか、AlphaCompositeではなく 別のクラスを使うのか、そもそも APIではできなくてドットを一個一個書い ていく必要があるのか・・? ご存じの方がいましたら、なにとぞご教授、お願いいたします。 public BufferedImage mergeTwice(BufferedImage baseImage, BufferedImage layImage) { // BufferedImage を Graphic2D に変換 Graphics2D baseGra = baseImage.createGraphics(); Graphics2D layGra = layImage.createGraphics(); // 2つの画像を合成 AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f); baseGra.setComposite( composite ); baseGra.drawImage(layImage, 0, 0, null); AlphaComposite composite2 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f); return baseImage; }

  • javaで画像を表示したのですが、変です。

    画像をのせたのですが、表示した画像の透明部分のところに予期しない形で画像が重なってしまいます。 また、ウィンドウのサイズを何回かスクロールしていじると元に戻ります。 文字数の関係ですべてのソースを乗せられないのですが、自作画像クラスだけ記載します。 import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JPanel; public class Layer extends JPanel { BufferedImage image; int x=0,y=0; //表示サイズ int lx=0,ly=0; //表示場所 int originalX,originalY; int startX,startY; Layer(){ } public void p(String imgpath,int lX,int lY,int X,int Y){ x=X;y=Y;lx=lX;ly=lY; image=Imagedraw(imgpath); } public void p(String imgpath,int lX,int lY){ lx=lX;ly=lY; image=Imagedraw(imgpath); x=originalX; y=originalY; setSize(x,y); } public void p(String imgpath){ image=Imagedraw(imgpath); x=originalX; y=originalY; setSize(x,y); } public BufferedImage Imagedraw(String imgpath){ BufferedImage img=null; try{ img = readImage(imgpath); }catch(Exception e){ e.printStackTrace(); } setLocation(lx,ly); setSize(x,y); return img; } public void setLocation(int lX, int lY){ lx=lX;ly=lY; super.setLocation(lx,ly); } public void paint(Graphics g){ //イメージを描画 g.drawImage(image,0,0,x,y,startX,startY,x+startX,y+startY,this); } public BufferedImage readImage(String path) throws IOException{ BufferedImage img; img = ImageIO.read(new File(path)); originalX=img.getWidth(); originalY=img.getHeight(); return img; } } どなたか原因に心当たりのある方、よろしくお願いいたします。 なお、画像はインターネット上での拾いものです。書かれた方には感謝いたします。

  • Java BufferedImage

    こんにちは。趣味でプログラミングをしている者です。 さっそくですが質問させていただきます。 JFileChooser から gif ファイルを取得し その画像上に文字列を重ねるようなツールのようなものを 作っているのですが、 加工された状態の画像を表示したいのですが、 もとの画像が表示されてしまいます。 以下のコードをみていただいて、どこが悪いのか 教えていただけないでしょうか? よろしくお願いします。 import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.io.*; import javax.imageio.ImageIO; import javax.swing.*; import javax.swing.filechooser.*; class DrawPanel extends JPanel implements ActionListener { JButton btOpen; JButton btSave; JFileChooser chooser; FileNameExtensionFilter filter01; FileNameExtensionFilter filter02; BufferedImage newImage; DrawPanel() { super(); setLayout( null ); setPreferredSize( new Dimension( 200, 240 )); setBackground( new Color( 220,240, 230 )); btOpen = new JButton( "open"); btSave = new JButton( "save"); btOpen.addActionListener( this ); btSave.addActionListener( this ); add( btOpen ); add( btSave ); btOpen.setBounds( 0,0, 100,40 ); btSave.setBounds( 100,0, 100, 40 ); chooser = new JFileChooser(); filter01 = new FileNameExtensionFilter( "gif files", "gif" ); filter02 = new FileNameExtensionFilter( "jpg files", "jpg" ); chooser.setFileFilter( filter01 ); chooser.addChoosableFileFilter( filter02 ); newImage = null; } public void actionPerformed( ActionEvent ae01 ) { if( ae01.getSource() == btOpen ) { int retvalue = chooser.showOpenDialog( null ); if( retvalue == JFileChooser.APPROVE_OPTION ) { String filename = (String) chooser.getSelectedFile().getAbsolutePath(); try { newImage = ImageIO.read( new File( filename ) ); } catch( Exception e01 ) { e01.printStackTrace(); newImage = null; } // (a) if( newImage != null) { Graphics2D g2D = newImage.createGraphics(); g2D.setColor( Color.red ); Font font01 = new Font( "Monospaced", Font.ITALIC, 18 ); g2D.setFont( font01 ); g2D.drawString( "AC", 5, 5 ); } // (a) の終わり repaint(); } } } public void paintComponent( Graphics g ) { super.paintComponent(g); Graphics2D drawG2D = (Graphics2D) g; if( newImage == null ) { drawG2D.setColor( Color.green ); drawG2D.fillRect( 15, 50, 55, 70 ); } else { drawG2D.drawImage( newImage, 15, 50, this ); } } } ------------------------------------------------------ class test03 extends JFrame { DrawPanel dp01; test03() { super("filedialog test"); setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); dp01 = new DrawPanel(); add( dp01 ); setResizable( false ); setLocation( 170,300 ); pack(); setVisible( true ); } public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ new test03(); } } ------------------------------------------- (a) のところが悪いのだと思うのですが どのようにしたらよいのかわかりません 長文になり申しわけありませんが、 よろしくお願いします。

    • ベストアンサー
    • Java
  • 先に計算したほうがいいのでしょうか?

    下記のプログラムを作ったのですが、 Math.PI / 180 の部分は先に計算しておいたほうが処理が 早くなると言われたのですがそうなのでしょうか? 先に掛け算をしないといけないような気がするのですが。 import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; import java.lang.Math; public class Test9 { public static void main(String[] args) { int r = (args.length > 0)? Integer.parseInt(args[0]):100; int n = (args.length > 1)? Integer.parseInt(args[1]):16; int x, y, x1, y1; try { BufferedImage image=new BufferedImage(r*2+10,r*2+10,BufferedImage.TYPE_INT_RGB); Graphics2D g2d=image.createGraphics(); g2d.setBackground(Color.WHITE); g2d.clearRect(0,0,r*2+10,r*2+10); g2d.setColor(Color.BLACK); for ( double i = 0.0; i < 360.0; i += 360.0 / n ) { x1 = (int) ( r * Math.cos( i * Math.PI / 180 ) ); y1 = (int) ( r * Math.sin( i * Math.PI / 180 ) ); for( double j = i + 360 / n; j < 360.0; j += 360.0 / n ) { x = (int) ( r * Math.cos( j * Math.PI / 180 ) ); y = (int) ( r * Math.sin( j * Math.PI / 180 ) ); g2d.drawLine( x1 + r + 5, y1 * (-1) + r + 5, x + r + 5, y * (-1) + r + 5 ); } } ImageIO.write(image, "JPEG", new File("c:\\test9.jpg")); } catch(Exception e) { e.printStackTrace(); } } }

    • ベストアンサー
    • Java
  • 一次元配列から画像を生成するとき。。。

    お世話になります。 カラー画像をjavaプログラムで読み込み、グレースケース化して画像を生成したいのですが、最後の画像生成の部分がうまくいきません。具体的には、 Image img_gray = createImage(new MemoryImageSource(w idth,height,rgb_gray,0,width)); として、img_grayという画像ファイルに変換しようとしています。しかし、コマンドプロンプトでコンパイルしようとすると、 C:\QR>javac Sample.java Sample.java:78: static でない メソッド createImage(java.awt.image.ImageProducer) を static コンテキストから参照することはできません。 Image img_gray = createImage(new MemoryImageSource(width,height, rgb_gray,0,width)); というエラーが出てしまいます。原因が分かりません。どなたか解決策を教えていただける方おられましたらよろしくお願いします。 以下にソースを貼っておきます。 import java.io.*; import java.lang.*; import java.awt.*; import java.awt.Color; import java.awt.color.ColorSpace; import java.awt.event.*; import javax.swing.*; import javax.imageio.ImageIO; import javax.media.*; import javax.media.control.*; import javax.media.format.*; import javax.media.util.*; import java.awt.image.*; import java.applet.*; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import java.io.File; import java.io.IOException; import java.util.*; import java.text.*; public class Sample extends JPanel{ static BufferedImage image; //static BufferedImage change_image; public static void main(String[] args) { //************************************************************************************************ try { //画像ファイルのデータを読み込む image = ImageIO.read(new File("C:\\QR\\imagefile\\sa.bmp")); } catch (Exception e) { e.printStackTrace(); image = null; } // *********************************************************************************************** //グレースケール int i,j,r,g,b,d; Color color; int width = image.getWidth(); int height = image.getHeight(); int size = width * height; int[] rgb_src=new int[size]; int[] rgb_gray=new int[size]; PixelGrabber grabber= new PixelGrabber(image,0,0,width,height,rgb_src,0,width); try{ grabber.grabPixels(); //画像imageを配列rgb_src[]に読み込む }catch(InterruptedException e){} //カラー画像をグレイ化する for(i=0;i<size;i++){ color=new Color(rgb_src[i]); r=color.getRed(); //赤の成分を取り出す g=color.getGreen(); //緑の成分を取り出す b=color.getBlue(); //青の成分を取り出す d=(int)(r*0.299+g*0.587+b*0.114); //グレイの成分を作る(NTSC方式準拠) color=new Color(d,d,d); rgb_gray[i]=color.getRGB(); } Image img_gray = createImage(new MemoryImageSource(width,height,rgb_gray,0,width)); } }

    • ベストアンサー
    • Java
  • Graphicsからの画像出力

    今javaで音場シミュレーションを行っているのですが、音場解析結果の Image を Graphics2D に変換し、JFreeChart で生成した時刻歴、FFTなどの結果を Graphics2D に グラフで貼り付けています。 Graphics2D g2 は以下のよう |--------| |音場結果| |--------| |グラフ6コ| |--------| 今これを画像出力したいのです。 調べると Image クラスのオブジェクトであれば、 ImageIO.write(image, "jpeg", new File(fileName)); のようにして出力できるようですが、Graphics(2D) から画像出力は可能でしょうか。

  • 同じ解像度でもサイズが違う画像について

    google画像検索などで画像を調べていると、 同じが解像度の画像でもファイルサイズが、500KBだったり1BMだったり、 数倍違うものがあります。 解像度は同じでも一般的にファイルサイズが大きいほど画質が良いという 解釈でいいのでしょうか?

専門家に質問してみよう