JPEG画像の書き出し

このQ&Aのポイント
  • JPEG画像を読み込んで別ファイルに出力する方法と、画素値の変更をしない方法について解説します。
  • JPEG画像の読み込みと出力には、JPEGImageDecoderとJPEGImageEncoderを使用します。
  • 圧縮を行わずにオリジナルの画素値を保持したまま出力するには、JPEGEncodeParamの設定が必要です。
回答を見る
  • ベストアンサー

JPEG画像の書き出し

JPEG画像を読み込んで別ファイルに出力するという操作を行いたくて、以下のように書きました。 //画像情報の取得 try { FileInputStream fis = new FileInputStream(fileName); JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(fis); image = decoder.decodeAsBufferedImage(); fis.close(); } catch (IOException e) { System.err.println("Can't open the file."); } //** 中略 **// //画像情報の出力 try{ FileOutputStream fos = new FileOutputStream(fileName); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(fos); JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image); param.setQuality((float)1.0, false); encoder.setJPEGEncodeParam(param); encoder.encode(image); fos.close(); } catch (IOException e){ System.out.println("Can't save the new file."); } これで、実際に入出力はできるのですが、圧縮されるのかオリジナルとは違うものが出力されてしまいます。 コピーではなく、画素値の変更が一切ないように出力したい場合はどうしたらいいでしょうか?

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

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

  • ベストアンサー
  • bgbg
  • ベストアンサー率53% (94/175)
回答No.1

JPEG画像を読み込んで、何らかの加工を施し、その結果を出力させるということでしょうか。 省略されている部分でどのような処理を行っているか気になります。 何も加工をしないのならJPEGImageEncoderにデータを読み込ませる必要はなく、FileInputStreamで読み込んだデータをそのままFileOutputStreamに書き込めばいいでしょう。 何らかの加工をする場合は、画像を一度復号して再圧縮するという過程は免れません。 どうしても可逆圧縮の画像を使いたいのならGIFやPNGを使ってください。

noname#232871
質問者

お礼

画素値を一部操作しています。 それ以外のところを変化なしで出力したかったのですが…。 JPEGだと否応なしに圧縮されてしまうんですね。 違う形式の使用も検討してみます。 ありがとうございました。

関連するQ&A

  • UNICODEへの文字コード変換

    以下のようにして、 日本語で書かれたファイルを読み込んで、 UNICODEに変換したいのですが、 できません。。。 どこが間違っているのでしょうか?(;;) 元の日本語ファイル「こんにちは」 >>できたファイル「\u3053\u3093\u306b\u3061\u306f」 という風にしたいのですが。。 //FileIOSteramの作成 FileInputStream fis = new FileInputStream(iFile); FileOutputStream fos = new FileOutputStream(oFile); //Stream ラップ InputStreamReader in = new InputStreamReader(fis, "EUC-JP-LINUX"); OutputStreamWriter out = new OutputStreamWriter(fos, "UTF16"); System.out.println(System.getProperty("file.encoding")); //読み込みと書き込み int c; InputStreamReader in = new InputStreamReader(fis, "Unicode"); Writer out = new Writer(fos); while((c = in.read()) != -1){ out.write(c); }

  • Return で文字列が返せない、、

    このような関数を作って、mainの関数に渡したいのですが、文法がダメだとコンパイラに怒られます。 private String test(){ try{ FileOutputStream fos=openFileOutput("sample.txt", MODE_PRIVATE); String text="サンプルテキストです"; fos.write(text.getBytes()); fos.close(); }catch(FileNotFoundException e){ }catch(IOException e){ } try{ FileInputStream fis=openFileInput("sample.txt"); byte buffer[]=new byte[100]; fis.read(buffer); String str = new String(buffer).trim(); fis.close(); return str; }catch(FileNotFoundException e){ }catch(IOException e){ } }なぜ返せないのでしょうか。

    • ベストアンサー
    • Java
  • ストリームの問題について【至急】

    import java.io.*; public class FileStreamDemo { public static void main(String[] args){ try{ byte[] buffer=new byte[1024]; FileInputStream fileInputStream= new FileInputStream(new File(args[0])); FileOutputStream fileOutputStream= new FileOutputStream(new File(args[1])); System.out.println("コピーファイル: "+fileInputStream.available()+"バイト"); while(true){ if(fileInputStream.available()<1024){ int remain=-1; while((remain=fileInputStream.read())!=-1){ fileOutputStream.write(remain); } break; } else{ fileInputStream.read(buffer); fileOutputStream.write(buffer); } } fileInputStream.close(); fileOutputStream.close(); System.out.println("コピー完了"); } catch(ArrayIndexOutOfBoundsException e){ System.out.println( "using:java FileStreamDemo src des"); e.printStackTrace(); } catch(IOException e){ e.printStackTrace(); } } } JAVAの入門者です。 JAVAの教科書に書いてあるように、上のプログラムを書きましたけど… コンパイルすると、エラーメッセージが出て来ます。 エラー中身は下記のとおりです。 【using:java FileStreamDemo src des java.lang.ArrayIndexOutOfBoundsException: 0 at FileStreamDemo.main(FileStreamDemo.java:8) 】 どうすればいいのか悩んでいます。 誰か、助けていただけないのでしょうか?どこか間違ってるか、教えてください。 よろしく、お願いします。

  • ファイル圧縮について。

    ファイル圧縮について質問させてください。 以下のようなメソッドを作成したのですが、 public run(String strFiles[], String strZipFileName) { int i = 0; int iLen = 0; FileInputStream fis = null; FileOutputStream fos = null; ZipOutputStream zos = null; ZipEntry zent = null; byte[] buf = new byte[1024*10*10]; try { fos = new FileOutputStream(strZipFileName); zos = new ZipOutputStream(fos); for (i = 0; i < strFiles.length(); i++) { fis = new FileInputStream(strFiles[i]); zent = new ZipEntry(strFiles[i]); zos.putNextEntry(zent); while (-1 != (iLen = fis.read(buf))) { zos.write(buf, 0, iLen); } zos.flush(); zos.closeEntry(); fis.close(); } } catch(Exception e) { System.err.println(e); } finally { try { zos.close(); // ※1 fos.close(); // ※2 } catch(Exception e) { System.err.println(e); } } } サイズの小さいファイルや、 特定のサイズのファイル(13k程度)を対象とした時、 高い確率で、空の圧縮ファイルが作成される事があります。 ログを出力しながら確認すると、このような現象が起きた場合、 圧縮ファイルをcloseする直前(※1)では作成されたファイルはサイズがあるのですが、 圧縮ファイルをcloseした直後(※2)ではファイルのサイズが0になってしまいます。 また、2台あるサーバの内、1台だけでこの現象が起こっています。 javaのバージョンは1.3です。 何故このような現象が起こってしまうのか、 ご存知の方がいらっしゃいましたら教えていただけないでしょうか。 宜しくお願いします。

    • ベストアンサー
    • Java
  • プログラミングを始めたばかりの初心者です

    プログラミングを始めたばかりの初心者で、行き詰っていることがあります。 Windows環境でjavaのプログラミングをしています。(JDK1.7.0_03) InputFileというファイルを、指定したバイト単位で文字を切り出し、新たなOutputFileという ファイルに書き出したいのですが、以下の例のように、全角マイナスだけが?と表示されて しまい、うまくいきません。 InputFile 田中太郎 tanaka tarou  タナカタロウ 田中町1-1-1 06011112222・・・ 吉田花子 yoshida hanako ヨシダハナコ 吉田町2-2-2 01011113333・・・ 山田良子 yamada yoshiko ヤマダヨシコ 山田町3-3-3 02011115555・・・ OutputFile 田中太郎 tanaka tarou  タナカタロウ 田中町1?1?1 06011112222・・・ 吉田花子 yoshida hanako ヨシダハナコ 吉田町2?2?2 01011113333・・・ 山田良子 yamada yoshiko ヤマダヨシコ 山田町3?3?3 02011115555・・・ お見せするのも恥ずかしい滅茶苦茶なソースかもしれませんが現状は以下の通りです。 どなたか教えていただけないでしょうか。よろしくお願い致します。 (読み込むInputFileというファイルの文字コードはEUCです。) ソース import java.io.*; class ReadTest{ static LineNumberReader inr; static InputStreamReader isr; static String FN = "InputFile"; static OutputStreamWriter osw; public static void main(String[] args) { String line; try { FileInputStream fis = new FileInputStream(FN); isr = new InputStreamReader(fis,"EUC_JP"); inr = new LineNumberReader(new BufferedReader(isr)); FileOutputStream fos = new FileOutputStream("OutputFile"); osw = new OutputStreamWriter(fos,"EUC_JP"); BufferedWriter bw = new BufferedWriter(osw); while ((line = inr.readLine()) != null) { bw.write(new String(line.getBytes(),0,120)); bw.newLine(); } System.out.println(inr.getLineNumber() + "件読み込み完了"); fis.close(); isr.close(); bw.close(); fos.close(); } catch (IOException e) { System.out.println(e); } } }

  • Try-catch文(FileInputStream)

    下記コードでエラーが出現して困っています。 fis.close();の部分でコンパイルエラー( 変数 fis は初期化されていない可能性があります。)の結果が返ってきます。 必ず通過するfinallyブロックにclose()処理を記述して、この処理もエラーが発生する可能性があるので、try-catchする必要があると教師が言っていました。 エラーが出現する原因はなぜでしょうか? 回答のほどよろしくお願い致します。 FileInputStream fis; try{ fis = new FileInputStream(fi.getAbsolutePath()); while( (b[i++] = fis.read()) != -1); }catch(FileNotFoundException e){ } catch(IOException e){ }finally{ try{ fis.close(); ←コンパイルエラー( 変数 fis は初期化されていない可能性があります。) }catch(IOException e){ } }

    • ベストアンサー
    • Java
  • javaの文字化け

    自分はプログラミング初心者です。以下のようなプログラムで新しいメモ帳ファイルに数字を出力しようとすると文字化けしてしまいます。どうすれば文字化けを直せるのでしょうか? よろしくお願いします。 import java.io.*; class Number { public static void main(String args[]) { try { FileOutputStream fos = new FileOutputStream(args[0]); DataOutputStream dos = new DataOutputStream(fos); int count = 0; int j = 1; do { dos.writeShort(j); j += 3; } while(++count < 15); fos.close(); } catch(Exception e) { System.out.println("Exception: " + e); } } }

    • ベストアンサー
    • Java
  • 固定長データのbyteスキップについて

    バイナリ入出力でご質問がございます。 下記の例のように各レコードにある 先頭5byte付与されたデータを スキップ(破棄)して 各レコード10byteずつ読み込みたいのですが なにかサンプルデータもしくは アドバイス頂けないでしょうか? どうぞよろしくお願い致します。 例 1レコード 10byte (先頭5byte付与) LLLLL1234567890 LLLLL1234567890 LLLLL1234567890 LLLLL1234567890 LLLLL1234567890 ↓ 1234567890 1234567890 1234567890 1234567890 1234567890 import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.io.ByteArrayOutputStream; public class dat{ public static void main(String[] args) { String inputFileName = ""; String outputFileName = ""; // ファイルオブジェクトの生成 File inputFile = new File(inputFileName); File outputFile = new File(outputFileName); try { FileInputStream fis = new FileInputStream(inputFile); BufferedInputStream bis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream(outputFile); BufferedOutputStream bos = new BufferedOutputStream(fos); byte[] buf = new byte[17]; int len = 0; while ((len = bis.read(buf, 0, 17)) == 17) { bos.write(buf, 0, 17); } bos.flush(); bos.close(); bis.close(); } catch(Exception e) { e.printStackTrace(); } }

    • ベストアンサー
    • Java
  • レコード長からのbyteスキップ設定について

    QNo.8229324から あらたに新規でご質問させて頂きます。 1レコードごとに10byteあったとします。 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 レコード長からスキップ設定を35byteと設定したとします。 40byteごとに頭の付与された5byteをスキップさせたいのですが なにかサンプル及びアドバイス頂けますでしょうか? 仕様案 (1)まずはレコード先端の5byteをスキップ (2)次は35byteを超えた時点で5byteスキップを繰り返し。 どうぞ宜しくお願い致します。 import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.io.ByteArrayOutputStream; public class dat{ public static void main(String[] args) { String inputFileName = ""; String outputFileName = ""; // ファイルオブジェクトの生成 File inputFile = new File(inputFileName); File outputFile = new File(outputFileName); try { FileInputStream fis = new FileInputStream(inputFile); BufferedInputStream bis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream(outputFile); BufferedOutputStream bos = new BufferedOutputStream(fos); byte[] buf = new byte[17]; int len = 0; while ((len = bis.read(buf, 0, 17)) == 17) { bos.write(buf, 0, 17); } bos.flush(); bos.close(); bis.close(); } catch(Exception e) { e.printStackTrace(); } }

    • ベストアンサー
    • Java
  • ファイル転送が正常に動作しない

    サーバ側からクライアント側へファイル転送をJavaで行おうとしています。 そこで以下のようなプログラムを作成し、実行するのですが 実行自体はうまくいき、1つめのファイルはきちんと転送できるのですが、 2つめのファイルが転送完了後に確認すると0バイトとなっており、 きちんと動作しません。どうするべきでしょうか。 サーバ側 ※上でソケットはつないであります。 if(command.equals("put.") == true){ System.out.println("putモードに入りました"); // カーネル(linux.uml)の送信 String filename1 = args[1]; byte[] data1 = new byte[1024]; //ストリームの作成 FileInputStream fin1= new FileInputStream(filename1); BufferedOutputStream out2 = new BufferedOutputStream(sock.getOutputStream()); System.out.println("送信ファイル : " + filename1); //int totalSize1 = 0; int len1; while((len1 = fin1.read(data1)) != -1){ out2.write(data1); } out.flush(); fin1.close(); System.out.println(filename1 + "を送信完了しました"); // ルートファイルシステム(uml-root-hardy)の送信 String filename2 = args[2]; byte[] data2 = new byte[1024]; //ストリームの作成 FileInputStream fin2 = new FileInputStream(filename2); //ファイルの内容を読み出し、送信する System.out.println("送信ファイル" + filename2); //long totalSize2 = 0; long len2 = 0; while((len2 = fin2.read(data2)) != -1){ out2.write(data2); } out.flush(); fin2.close(); System.out.println(filename2 + "を送信完了しました"); } クライアント側 ※上でソケットはつないであります。 if(change.equals("put.") == true){ System.out.println("putモードに入りました"); // 2つのファイルを転送する // カーネル(linux.uml)の転送 String filename1 = args[2]; System.out.println("受信するファイル : " + filename1); // FileOutputStreamの作成 FileOutputStream fout1 = new FileOutputStream(filename1); BufferedInputStream in2 = new BufferedInputStream(sock.getInputStream()); int recvMsgSize1; int bufSize = 1024; byte[] byteBuffer1 = new byte[bufSize]; //int totalByte1 = 0; while((recvMsgSize1 = in2.read(byteBuffer1)) != -1){ fout1.write(byteBuffer1); } System.out.println(filename1 + "を受信完了しました"); fout1.close(); // ルートファイルシステム(uml-root-hardy)の転送 String filename2 = args[3]; System.out.println("受信するファイル : " + filename2); FileOutputStream fout2 = new FileOutputStream(filename2); long recvMsgSize2; //byte[] byteBuffer = new byte[bufSize]; byte[] byteBuffer2 = new byte[bufSize]; //long totalByte2 = 0; while((recvMsgSize2 = in2.read(byteBuffer2)) != -1){ fout2.write(byteBuffer2); } System.out.println(filename2 + "を受信完了しました"); fout2.close(); } またプログラム中では、サーバ、クライアントでそれぞれ len1,len2(サーバ側)、recvMsgSize1,recvMsgSize2(クライアント側) に警告で「ローカル変数len1(recvMsgSize1)は読み取られません」 と出ています。 どのように解決するべきでしょうか。

    • ベストアンサー
    • Java

専門家に質問してみよう