javaで画像を回転、縮小するにはどのようにすればよいでしょうか?

なるべく画質の良い方法で教えてください。

よろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

javaで標準で使える画像のアフィン変換(補填)アルゴリズムは、 nearest-neighbour、bilinear、bicubicで、左から順に画質が基本的に向上し、そのかわり計算コストが高くなります。




下記ソースは
http://www.java-tips.org/java-se-tips/javax.imag …
からもらってきたもので、いらんとこを消してあります。

一番画質の良いbicubicを使っています。



import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.swing.*;
import javax.imageio.*;

public class Bicubic {
public static void main(String args[]) throws IOException {
if (args.length == 0) {
System.err.println(
"Provide image name on command line");
System.exit(-1);
}
Image image = ImageIO.read(new File(args[0]));
int w = image.getWidth(null);
int h = image.getHeight(null);
BufferedImage bicubic = new BufferedImage(2*w, 2*h,
BufferedImage.TYPE_INT_RGB);

bg = bicubic.createGraphics();
bg.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
bg.scale(2, 2);
bg.drawImage(image, 0, 0, null);
bg.dispose();

}
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qjavaで画像のトリミングをする方法

ご存知の方がおられましたら、教えてください。
画像ファイルのトリミングをJavaで行いたいと思っておりますが、
縦横維持した画像の縮小はできたのですが、
トリミングができなくて困っています。
例)
幅:240ピクセル、高さ:320ピクセルの画像を
幅:130ピクセル、高さ:106ピクセルにしたいのですが、
縦横維持した場合、幅を基準にすると、
幅:130ピクセル、高さ:173ピクセルになるため、
この画像の高さを106にトリミングしたいのです。

よい方法をご存知の方おられましたら、
是非ご教授のほど、よろしくお願いいたします。

Aベストアンサー

例えばこんな方法ではどうでしょうか。

BufferedImage mainImage=ImageIO.read(new File("originalImage.png"));
BufferedImage subImage=mainImage.getSubimage(0,0,130,106);

ImageIO.write(subImage,"PNG",new File("trimmedImage.png"));

Qinterface,extend,implementのちがい

お世話になります、

Javaを勉強しているのですが、
interface,extend,implementの使い分けがわかりません。

私の解釈としては、
(1)interfaceは、グローバル変数の定義、グローバルメソッドの定義(実装はしない)。

(2)extendは、extendクラスを親クラスとして親クラスの機能を使用できる。

(3)implementは…,implementもextendと同じような意味だと解釈しているんですが、違う点は、implementで定義してあるメソッドは、使用しなくても、実装しなければならないという点でしょうか?

とにかくこの3つのを使い分けるコツとかあれば教えてください。
よろしくお願いします。

Aベストアンサー

バラバラに理解してもしょうがないッス。

まず、
(1)interface と implements
(2)class と extends

が対応しているわけっす。

JavaはC++と違って、比較的言語仕様を「簡単」にしたので「多重継承」という
概念がないです。
多重継承っていうのは、複数のクラスを親クラスにして継承するってことですね。

たとえば、 「TextFieldクラス」と「Japaneseクラス」を多重継承すると、
「JTextFieldクラス」ができるっていうのが自然な考え方でしょう?

まぁ、例えば、日本語クラスであれば、getStringLength()メソッドなどが
あったほうが良いでしょうか。
このgetStringLength()メソッドは、2バイト文字も1バイト文字も「1文字」
と数えてくれると言う点で、まさに、日本語クラス用のメソッドだと言えるでしょう。

例えば、Java的に記述すると、、、
class Japanese {
public int getStringLength() {
  ・・・
return strlength;
 }
 ・・・
}

class TextField {
・・・
}

class JTextField extends TextField, extends Japanese {
・・・・
}

C++ではそのように実装するでしょう。
しかし、Javaにはこのような高度な機能はありません。

そこで、生まれた苦肉の策が、「interfaceとimplements」です。

interface Japanese {
public int getStringLength(); // interfaceは実装を含まない!
                 // すなわち「実装の継承」ができるわけではない。
}

class TextField {
・・・
}

class JTextField extends TextField implements Japanese {
・・・・
public int getStringLength() {
  ・・・
return strlength; //implementsの実装を「各クラスで」実装してやる必要がある。
 }
}


結局のところ、Javaでは、複数のクラスを親クラスには持ち得ないため、継承できなかったクラスは「各クラスで実装してやる必要性」があるのです。


ではどのように使うのが効果的か?

なまえのままです。「代表的なインターフェイス」にたいしてinterfaceを使うのが良いと思います。

例えば、プレイヤー系であれば、ビデオ・コンポ・ウォークマン・などにかかわらず、
interface controlpanel {
public play();
public stop();
public next();
public back();
}
というような基本的インターフェイスを「持っているべき」です。

こうすることで、それぞれのクラス宣言の際に、これらの「インターフェイスを持っているべきであり、実装されるべきである」ということを「強く暗示」することができます。
class videoplayer extends player implements controlpanel {
public play() {・・・}
public stop() {・・・}
public next() {・・・}
public back() {・・・}
}

こうすることで、同様のクラスを作成するユーザーは、
「プレイヤー系は、4つ操作が出来るコントロールパネルをインターフェイスとして持つべきなのだな!?」という暗示を受け取り、自分のクラスでもそれを模倣するでしょう。

class mp3player extends player implements controlpanel {
public play() {・・・}
public stop() {・・・}
public next() {・・・}
public back() {・・・}
}

また、これらのクラスを使用するユーザーも、「implements controlpanel」という
表記を見て、「4つの基本操作は押さえられているのだな!」という基本中の基本動作を抑えることが出来ます。

まとめると、クラスに「こういう特徴もたしてください!」「こういう特徴持ってますよ!」という一種の暗示的警告や方向性を与えることができるわけですね。

バラバラに理解してもしょうがないッス。

まず、
(1)interface と implements
(2)class と extends

が対応しているわけっす。

JavaはC++と違って、比較的言語仕様を「簡単」にしたので「多重継承」という
概念がないです。
多重継承っていうのは、複数のクラスを親クラスにして継承するってことですね。

たとえば、 「TextFieldクラス」と「Japaneseクラス」を多重継承すると、
「JTextFieldクラス」ができるっていうのが自然な考え方でしょう?

まぁ、例えば、日本語クラスであれば...続きを読む

QKeyListenerの使い方について

FrameクラスのフレームにKeyListenerをaddKeyListenerで登録してキー入力を受け付けたいのですが、キーを入力してもまったく反応がありません。どうやらkeyTyped,keyPressed,keyReleasedのどのメソッドも呼び出されてないようです。クラスの概要は以下のとおりです。
class sampleFrame extends Frame implements KeyListener
{
{
addKeyListener(this);//コンストラクタ内で登録
}



で、keyPressedとうのメソッドはすべて定義しています。それから、キーを入力するとなぜか同じフレーム上のリストボックスの項目が入れ替わったりします。
どうぞよろしくお願いいたします。

Aベストアンサー

こんにちは。
おそらくフォーカスの問題だと思います。
フォーカスをフレームに設定してあげれば良いのですが、一度でも内部のコンポーネントに(クリックするなど)フォーカスを設定すると、フォーカスをフレームに再設定する仕掛けを用意しておく必要があります。
- - -
import java.awt.*;
import java.awt.event.*;

public class Test extends KeyAdapter {

Frame frame;
List list;

public static void main(String args[]) {
new Test();
}

public Test() {
list = new List();
list.add("apple");
list.add("orange");
list.add("banana");
list.removeKeyListener(this);

frame = new Frame("Test");
frame.add(list);
frame.setSize(400, 300);
frame.setLocation(100, 100);
frame.addKeyListener(this);
frame.show();
frame.requestFocus(); // フレームにフォーカスを設定
}

public void keyPressed(KeyEvent e) {
System.out.println("key pressed.");
}

}

こんにちは。
おそらくフォーカスの問題だと思います。
フォーカスをフレームに設定してあげれば良いのですが、一度でも内部のコンポーネントに(クリックするなど)フォーカスを設定すると、フォーカスをフレームに再設定する仕掛けを用意しておく必要があります。
- - -
import java.awt.*;
import java.awt.event.*;

public class Test extends KeyAdapter {

Frame frame;
List list;

public static void main(String args[]) {
new Test();
}

public Test() {
list = new List();
list....続きを読む

Qビットマップ(bmp)形式で背景を透過にできる?

Photoshop、Illustrator、ペイントのいずれかを使って、ビットマップ(bmp)形式で背景を透過にできますか?

Aベストアンサー

>(bmp)形式で
というのが、保存するファイル形式を指すのであれば、できません。

Q大きいサイズのテキストファイルの開き方

いつもお世話になっています。
愚問ですが、ご存知の方、ご回答をお願いします。

あるシステムを運用している中で、今迄誰も気が付かず
膨れ上がってしまったログファイル(テキスト)が4GB程あります。

これらを参照したいと思うのですが、当然のごとく
メモリオーバーが発生し開く事ができません。
このような大きいファイルを参照する術はありますでしょうか?
(あくまでも過去分を見たいので、このファイルを開きたいです)

##環境##
OS  Windows2000
CPU Celeron1.7GHz
メモリ 254MB

足りない情報があればご指摘下さい。
どうぞ、よろしくお願いします。

Aベストアンサー

そういう用途に特化したオンラインソフトを利用するとか。

GigaReader
http://www.vector.co.jp/soft/win95/util/se358341.html
鈴川エディタ
http://www.vector.co.jp/soft/winnt/writing/se367901.html

参考URL:http://www.vector.co.jp/soft/win95/util/se358341.html, http://www.vector.co.jp/soft/winnt/writing/se367901.html

QStrutsで画面遷移させない。

Strutsでwebアプリを作成しているのですが、jsp上のボタンを押下時、sessionに持ってる変数を書き換えたいのですが、画面遷移はさせたくないのです。それって可能ですか? どなたかご教授ください。

Aベストアンサー

画面遷移とは、サーバーサイドへのアクセスのことを想定されているのでしょうか?
それとも、表示されている画面の状態の変化のことでしょうか?

もし、後者であれば、Actionで自身の画面にforwardしてやればできます。

前者であるのなら難しいです。
sessionの値を書き換えたいのであれば、必ずサーバーサイドに要求を送らなければならないからです。
今、流行のAjaxを利用すれば、画面の遷移なしに可能です。

QImage を90度回転して、新しいImageを作成するには?

Image データがあったとして、それを90度回転させた別のImageを作成したいのですが、すごく時間がかかります。
もっといいやり方があると思うのですが、ネットで調べても方法が見つかりませんでした。
今採用しているのは下記のようなやり方です。
もっと短時間でImage作成できる、良い方法をご教授頂けないでしょうか?

PixelGrabber pg_f = new PixelGrabber(oldimg, 0, 0, oldw, oldh, old_pixel, 0, oldw);
try{
pg_f.grabPixels();
} catch (InterruptedException e){
return null;
}
int trans = ~0x00000000;
for (int x = 0; x < oldw; x++) {
for (int y = 0; y < oldh; y++) {
new_pixel[y + (newh - x - 1) * neww] = old_pixel[x + oldw * y] & trans;
}
}
Image new_img = Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(neww, newh, new_pixel, 0, neww));
MediaTracker mediaTracker = new MediaTracker(frame);
mediaTracker.addImage(new_img, 0);
try
{
mediaTracker.waitForID(0);
}
catch (InterruptedException ie)
{
System.err.println(ie);
System.exit(1);
}

Image データがあったとして、それを90度回転させた別のImageを作成したいのですが、すごく時間がかかります。
もっといいやり方があると思うのですが、ネットで調べても方法が見つかりませんでした。
今採用しているのは下記のようなやり方です。
もっと短時間でImage作成できる、良い方法をご教授頂けないでしょうか?

PixelGrabber pg_f = new PixelGrabber(oldimg, 0, 0, oldw, oldh, old_pixel, 0, oldw);
try{
pg_f.grabPixels();
} catch (InterruptedException e){
return null;
}
int tr...続きを読む

Aベストアンサー

Java には詳しくないので,PixelGrabber や MediaTracker が何で,
何をしているのかよく知りませんが,時間がかかっているのは
画像の回転を行っている2重ループの部分だと思います.
(そのことは確認しましたか? その部分と,それ以外の部分の実行時間は計ってみましたか?)

以下,その前提でとりあえずすぐ思いつく改良案を書きます.

(1) まず,最初に思いつくのは,trans=~0 で & を取っているのが無駄.
trans に別の値を入れる予定がなければ削除.

(2) 次に思いつくのは,配列の添字の1次式を毎回計算しているのが効率悪い.
乗算を使わず加算だけで行えるように添字の計算方法を変更した方がよい.

(3) 読み出し側の old_pixel[] の要素のアクセス順序がとびとびなので,
キャッシュの効きが悪い.要素が順番にアクセスされるよう,
xとyのループを入れ替えてみては?
(書き込み側の new_pixel[] のアクセス順序はどうなんだといわれると,
確かにそれも考慮する必要はあるが,それをやろうとするとかなり面倒に
なりそうなので,とりあえず考慮しないことにする.)

int i = 0;
int j = neww * newh;
for(int y = 0; y < oldh; y++, j++) {
int k = j;
for(int x = 0; x < oldw; x++, i++) {
k -= neww;
new_pixel[k] = old_pixel[i];
}
}

これでどうでしょうか?

Java には詳しくないので,PixelGrabber や MediaTracker が何で,
何をしているのかよく知りませんが,時間がかかっているのは
画像の回転を行っている2重ループの部分だと思います.
(そのことは確認しましたか? その部分と,それ以外の部分の実行時間は計ってみましたか?)

以下,その前提でとりあえずすぐ思いつく改良案を書きます.

(1) まず,最初に思いつくのは,trans=~0 で & を取っているのが無駄.
trans に別の値を入れる予定がなければ削除.

(2) 次に思いつくのは,配列の添字の1...続きを読む

Q描画処理が実行されない

while(gameflag==true){
(数値設定)   
repaint();
long start = System.currentTimeMillis();
while(System.currentTimeMillis()<start+1000){
}
}

上記のようにwhileループの中で数値などの設定を行い、描画をし、遅延をしているのですが他の処理はちゃんと実行されるのになぜか描画処理だけが行われません。また、whileループ外でも描画を行っていますがその時点ではきちんと描画されます。描画されない原因はどのようなことが考えられるでしょうか?描画はpaintComponent(Graphics g) メソッドで描画しています。

Aベストアンサー

>描画されない原因はどのようなことが考えられるでしょうか?

Swingの描画はダブルバッファを使っている関係上、描画メソッドを呼び出したときではなく、その後、もっとも早く再描画できるタイミングで表示を更新します。このため、while内で描画を行っている場合には、そのwhileを抜け、処理が終了した頃で表示が更新されるため、while中で行っている描画処理は見えません。(途中の描画は見えず、最終的に描画された状態だけが表示される)

この処理は、別スレッドを使って実行していますか? メインスレッドでは、上のような理由で途中の更新は見えませんから、マルチスレッドで実行し、描画ごとに強制的にrepaintするなどしてみてはいかがでしょう。

Q10進数の14.5を浮動小数点(IEEE754形式)の2進数に変換するにはどうしたらよいでしょうか?

10進数の14.5を浮動小数点(IEEE754形式)の2進数に変換するにはどうしたらよいでしょうか?
10進数の-7.5を浮動小数点(IEEE754形式)の2進数に変換するにはどうしたらよいでしょうか?
計算方法を教えてください。

Aベストアンサー

14.5を符号と指数と仮数に分けます。
符号は正の数なので符号は0
次に14.5を符号無し2進数に変換すると
1110.1
小数点を左に移動させて1だけ残すと
1110.1=1.1101*2^3
仮数は23ビットで小数点より右側だけなので、足りない分を0でうめて
11010000000000000000000
指数の3を127でバイアスするので
3+127=130
これを2進数に直すと
10000010
全て合わせると、
01000001011010000000000000000000
で、32ビットの2進数に変換できました。
同じように、-7.5を変換すると、
符号は負の数なので1
-7.5を符号無し2進数に変換すると、
 111.1
=1.111*2^2
なので、仮数は
11100000000000000000000
指数の2を127でバイアスすると
2+127=129
これを2進数に直すと
10000001
全て合わせると
11000000111100000000000000000000
になります。
64ビットの場合は、指数のバイアスを127から1023にし、仮数の23ビットを52ビットまで増やせばOKです。

14.5を符号と指数と仮数に分けます。
符号は正の数なので符号は0
次に14.5を符号無し2進数に変換すると
1110.1
小数点を左に移動させて1だけ残すと
1110.1=1.1101*2^3
仮数は23ビットで小数点より右側だけなので、足りない分を0でうめて
11010000000000000000000
指数の3を127でバイアスするので
3+127=130
これを2進数に直すと
10000010
全て合わせると、
01000001011010000000000000000000
で、32ビットの2進数に変換できました。
同じように、-7.5を変換すると、
符号は負の数なので1
-7.5を...続きを読む

Qcssで「下よせ」ってどうやっていますか?

フロートのレフト、ライトはいいとして、

あるボックス要素内(A)に異なるボックス要素(B)をいれます。
この(B)を(A)の一番そこにはりつかせたい時にどうすれば
最もよいのでしょうか?

いいアイデアをご教授ください。

Aベストアンサー

こんなのはどうかな?

position: absolute;
bottom: 0px;


人気Q&Aランキング

おすすめ情報