30. maj 2005 - 20:32Der er
5 kommentarer og 1 løsning
Billedbehandling - Resolution (DPI)
Hej Eksperter!
Jeg har et problem. Jeg vil gerne kunne lave en masse billeder mindre ved en funktion, og har fundet noget kode på nettet (se længere nede). Men hvis jeg har nogle billeder med en opløsning på 300 DPI, så laver funktionen dem mindre, til 96 DPI. Jeg vil gerne bibeholde de 300 DPI. Billedet skal bare blive mindre, og ikke andet...
Min nuværende kode ser således ud: ------------------------------
public static void doResize(String inputFile, String outputFile, int thumbWidth, int thumbHeight, int quality) throws Exception {
// load image from INFILE Image image = Toolkit.getDefaultToolkit().getImage(inputFile); MediaTracker mediaTracker = new MediaTracker(new Container()); mediaTracker.addImage(image, 0); mediaTracker.waitForID(0); // determine thumbnail size from WIDTH and HEIGHT
double thumbRatio = (double) thumbWidth / (double) thumbHeight; int imageWidth = image.getWidth(null); int imageHeight = image.getHeight(null); double imageRatio = (double) imageWidth / (double) imageHeight; if (thumbRatio < imageRatio) { thumbHeight = (int) (thumbWidth / imageRatio); } else { thumbWidth = (int) (thumbHeight * imageRatio); } // draw original image to thumbnail image object and // scale it to the new size on-the-fly BufferedImage thumbImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB); Graphics2D graphics2D = thumbImage.createGraphics(); graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); graphics2D.drawImage(image, 0, 0, thumbWidth, thumbHeight, 300, 300, 300, 300, null); // save thumbnail image to OUTFILE BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outputFile)); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); JPEGEncodeParam param = encoder. getDefaultJPEGEncodeParam(thumbImage);
public class Thumbnail { public static void main(String[] args) throws Exception {
doResize("bla.JPG", "bla2.jpg", 600, 600); }
public static void doResize(String inputFile,String outPutFile, int thumbWidth, int thumbHeight) throws Exception { // load image from INFILE Image image = Toolkit.getDefaultToolkit().getImage(inputFile); MediaTracker mediaTracker = new MediaTracker(new Container()); mediaTracker.addImage(image, 0); mediaTracker.waitForID(0); // determine thumbnail size from WIDTH and HEIGHT
double thumbRatio = (double) thumbWidth / (double) thumbHeight; int imageWidth = image.getWidth(null); int imageHeight = image.getHeight(null); double imageRatio = (double) imageWidth / (double) imageHeight; if (thumbRatio < imageRatio) { thumbHeight = (int) (thumbWidth / imageRatio); } else { thumbWidth = (int) (thumbHeight * imageRatio); } // draw original image to thumbnail image object and // scale it to the new size on-the-fly BufferedImage thumbImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB); Graphics2D graphics2D = thumbImage.createGraphics(); graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); graphics2D.drawImage(image, 0, 0, thumbWidth, thumbHeight, null);
int dpi[] = getImageDpi(inputFile); saveImageToDisk(thumbImage,dpi[0],dpi[1],outPutFile); }
// Here is a function to save a jpeg using ImageIO: private static void saveImageToDisk(BufferedImage bi, int dpix, int dpiy, String fileName) {
Iterator i = ImageIO.getImageWritersByFormatName("jpeg"); //are there any jpeg encoders available?
if (i.hasNext()) //there's at least one ImageWriter, just use the first one { ImageWriter imageWriter = (ImageWriter) i.next(); //get the param ImageWriteParam param = imageWriter.getDefaultWriteParam();
ImageTypeSpecifier its = new ImageTypeSpecifier(bi.getColorModel(), bi.getSampleModel());
//reset values for nodes resUnitsNode.setNodeValue("1"); //indicate DPI mode XdensityNode.setNodeValue(String.valueOf(dpix)); YdensityNode.setNodeValue(String.valueOf(dpiy));
} //end if (childNodes.item(k).getNodeName().equals("app0JFIF")) } //end if (n.getNodeName().equals("JPEGvariety") break; //we don't care about the rest of the children } //end if (n.getNodeName().equals("JPEGvariety"))
} //end for (int j = 0; j < nl.getLength(); j++)
try { iomd.setFromTree(formatName, node); } catch (IIOInvalidTreeException e) { e.printStackTrace(); //To change body of catch statement use Options | File Templates. } //attach the metadata to an image IIOImage iioimage = new IIOImage(bi, null, iomd); try { imageWriter.setOutput(new FileImageOutputStream(new File(fileName))); imageWriter.write(iioimage); } catch (IOException e) { e.printStackTrace(); } } //end if (i.hasNext()) //there's at least one ImageWriter, justuse the first one } //end public static void saveImageToDisk(BufferedImage bi, int dpi, String fileName)
/** * @param node * @param attributeName - name of child node to return * @return */ static Node getAttributeByName(Node node, String attributeName) { if (node == null) return null; NamedNodeMap nnm = node.getAttributes(); for (int i = 0; i < nnm.getLength(); i++) { Node n = nnm.item(i); if (n.getNodeName().equals(attributeName)) { return n; } } return null; // no such attribute was found } //end Node getAttributeByName(Node node, String attributeName)
af en eller anden grund går det meget langsomt hvis jeg ikke indlæser billedet med Image image = Toolkit.getDefaultToolkit().getImage(inputFile);
hvis jeg indlæser billedet med imageInput = ImageIO.createImageInputStream(new FileInputStream(inputFile));
og sender det videre til resizeren som et bufferedimage så tager det +1min at resize.
derfor bliver det indlæst både når jeg resizer og når jeg finder ud af DPI for billedet... hvis du ved at det altid vil være 300x300 så kan du droppe getImageDpi()
det nyttede ikke noget at lave det buffered image indlæst i getImageDpi() om til image igen .. den var stadig langsom til at resize.. jeg vil tror der er lagt en masse nye informationer på billedet der gør det langsomt.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.