2012-02-23 17 views
30

Próbuję zmienić rozmiar buforowanego obrazu. Jestem w stanie go zapisać i wyświetlić na jframe bez problemów, ale nie mogę zmienić rozmiaru. Wszelkie wskazówki, w jaki sposób mogę to zmienić, aby pracować i pokazać obraz jako 200 * 200 Plik byłoby świetnieBuforowana wielkość obrazu

private void profPic(){ 
    String path = factory.getString("bottle"); 
    BufferedImage img = ImageIO.read(new File(path)); 
} 


public static BufferedImage resize(BufferedImage img, int newW, int newH) { 
    int w = img.getWidth(); 
    int h = img.getHeight(); 
    BufferedImage dimg = new BufferedImage(newW, newH, img.getType()); 
    Graphics2D g = dimg.createGraphics(); 
    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
    RenderingHints.VALUE_INTERPOLATION_BILINEAR); 
    g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null); 
    g.dispose(); 
    return dimg; 
} 

Odpowiedz

39

Updated odpowiedź

nie mogę sobie przypomnieć, dlaczego my original answer działało, ale po przetestowane w oddzielnym środowisku, zgadzam się, oryginalna zaakceptowana odpowiedź nie działa (dlaczego powiedziałem, że to też nie pamiętam). To, z drugiej strony, czy praca:

public static BufferedImage resize(BufferedImage img, int newW, int newH) { 
    Image tmp = img.getScaledInstance(newW, newH, Image.SCALE_SMOOTH); 
    BufferedImage dimg = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB); 

    Graphics2D g2d = dimg.createGraphics(); 
    g2d.drawImage(tmp, 0, 0, null); 
    g2d.dispose(); 

    return dimg; 
} 
+2

To nie kompiluje - getScaledInstance zwraca obraz nie BufferedImage. – I82Much

+0

Przykład użyty został wyodrębniony z mojego przykładu roboczego, ale tak, to nie skompilowałoby się tak, jak jest. Zaktualizuję to teraz. – Ocracoke

+6

Nadal nie jest to bezpieczne - na moim MacBooku, np. Dostaję wyjątek ClassCastException - nie jest to gwarantowana konwersja. – I82Much

15

Jeśli wszystko co jest potrzebne do zmiany rozmiaru BufferedImage w metodzie resize, wówczas biblioteka Thumbnailator może to zrobić dość łatwo:

public static BufferedImage resize(BufferedImage img, int newW, int newH) { 
    return Thumbnails.of(img).size(newW, newH).asBufferedImage(); 
} 

powyższy kod zmieni rozmiar img, aby pasował do wymiarów newW i newH przy zachowaniu proporcji oryginalnego obrazu.

Jeśli wymagane jest utrzymanie proporcji nie jest wymagane i rozmiaru, aby dokładnie zadanych wymiarach, wówczas sposób forceSize mogą być stosowane w miejsce metody size:

public static BufferedImage resize(BufferedImage img, int newW, int newH) { 
    return Thumbnails.of(img).forceSize(newW, newH).asBufferedImage(); 
} 

Stosując metodę Image.getScaledInstance nie gwarantuje zachowania proporcji oryginalnego obrazu dla obrazu o zmienionym rozmiarze, a ponadto generalnie jest bardzo powolny.

Thumbnailator używa techniki do stopniowej zmiany rozmiaru obrazu, która może być several times faster than Image.getScaledInstance przy jednoczesnym osiągnięciu jakości obrazu, która jest na ogół porównywalna.

Nota prawna: Jestem opiekunem tej biblioteki.

+0

Thumbnailator niesamowite.! –

3

Klasa ta zmiana rozmiaru z pliku i uzyskać nazwę format:

import java.awt.Image; 
import java.awt.image.BufferedImage; 
import java.io.ByteArrayOutputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.util.Iterator; 
import javax.imageio.ImageIO; 
import javax.imageio.ImageReader; 
import javax.imageio.ImageWriter; 
import javax.imageio.stream.ImageInputStream; 
import org.apache.commons.io.IOUtils; 

public class ImageResizer { 

public static void main(String as[]) throws IOException{ 

    File f = new File("C:/Users/samsungrob/Desktop/shuttle.jpg"); 

    byte[] ba = resize(f, 600, 600); 

    IOUtils.write(ba, new FileOutputStream(new File("C:/Users/samsungrob/Desktop/shuttle_resized.jpg"))); 

} 




public static byte[] resize(File file, 
          int maxWidth, int maxHeight) throws IOException{ 
    int scaledWidth = 0, scaledHeight = 0; 

    BufferedImage img = ImageIO.read((ImageInputStream) file); 

    scaledWidth = maxWidth; 
    scaledHeight = (int) (img.getHeight() * ((double) scaledWidth/img.getWidth())); 

    if (scaledHeight> maxHeight) { 
     scaledHeight = maxHeight; 
     scaledWidth= (int) (img.getWidth() * ((double) scaledHeight/ img.getHeight())); 

     if (scaledWidth > maxWidth) { 
      scaledWidth = maxWidth; 
      scaledHeight = maxHeight; 
     } 
    } 

    Image resized = img.getScaledInstance(scaledWidth, scaledHeight, Image.SCALE_SMOOTH); 

    BufferedImage buffered = new BufferedImage(scaledWidth, scaledHeight, Image.SCALE_REPLICATE); 

    buffered.getGraphics().drawImage(resized, 0, 0 , null); 

    String formatName = getFormatName(file) ; 

    ByteArrayOutputStream out = new ByteArrayOutputStream(); 

    ImageIO.write(buffered, 
      formatName, 
      out); 

    return out.toByteArray(); 
} 


private static String getFormatName(ImageInputStream iis) { 
    try { 

     // Find all image readers that recognize the image format 
     Iterator iter = ImageIO.getImageReaders(iis); 
     if (!iter.hasNext()) { 
      // No readers found 
      return null; 
     } 

     // Use the first reader 
     ImageReader reader = (ImageReader)iter.next(); 

     // Close stream 
     iis.close(); 

     // Return the format name 
     return reader.getFormatName(); 
    } catch (IOException e) { 
    } 

    return null; 
} 

private static String getFormatName(File file) throws IOException { 
    return getFormatName(ImageIO.createImageInputStream(file)); 
} 

private static String getFormatName(InputStream is) throws IOException { 
    return getFormatName(ImageIO.createImageInputStream(is)); 
} 

}

0

to sprawdzić, to pomaga:

BufferedImage bImage = ImageIO.read(new File(C:\image.jpg); 

BufferedImage thumbnail = Scalr.resize(bImage, Scalr.Method.SPEED, Scalr.Mode.FIT_TO_WIDTH, 
             750, 150, Scalr.OP_ANTIALIAS); 
1

Oto kod, którego użyłem do zmiany rozmiaru obrazów buforowanych, bez zbędnych dodatków, dość szybko:

public static BufferedImage scale(BufferedImage src, int w, int h) 
{ 
    BufferedImage img = 
      new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
    int x, y; 
    int ww = src.getWidth(); 
    int hh = src.getHeight(); 
    int[] ys = new int[h]; 
    for (y = 0; y < h; y++) 
     ys[y] = y * hh/h; 
    for (x = 0; x < w; x++) { 
     int newX = x * ww/w; 
     for (y = 0; y < h; y++) { 
      int col = src.getRGB(newX, ys[y]); 
      img.setRGB(x, y, col); 
     } 
    } 
    return img; 
}