Avatar billede backupmand Nybegynder
09. november 2004 - 16:31 Der er 9 kommentarer og
2 løsninger

Reduktion af filstørrelse på PNG billede

Hej,
Jeg har benyttet JAI til at loade et billede fra en URL på webben. Det har lykkedes mig at skalere dette billede fra dets originale format ned til et mindre format. Billedet fylder dog stadig for meget i antal kb (ca. 52 kb). Jeg vil gerne have, at billedet skal fylde omkring 10 kb da det skal bruges et sted hvor det er en passende filstørrelse. Hvordan ville en reduktion af billedet kunne lade sig gøre? Hvis man nu bruger JAI? Jeg har forestillet mig, at det ville have noget at gøre med reduktion af antal bits, men hvilken metode, hvilken klasse? Kan man se et eksemplel?
Tak
Avatar billede backupmand Nybegynder
09. november 2004 - 16:47 #1
Jeg mener ikke reduktion af billedet, men reduktion af filstørrelsen
Avatar billede mikkelbm Nybegynder
09. november 2004 - 17:56 #2
Jeg har følgende metoder liggende, som jeg har lavet i forbindelse med et projekt.

Kig på dem, og se om det er noget du kan bruge:

  public static boolean saveImageAsJPG(BufferedImage img, String name, String path, float quality)
  {
    try
    {
      String wholePath;

      if (path.endsWith("\\"))
        wholePath = path + name + ".jpg";
      else
        wholePath = path + "\\" + name + ".jpg";

        // Billedet bliver skrevet i byte[] format til denne stream
      FileOutputStream output = new FileOutputStream(wholePath);

      ImageOutputStream imgOut = javax.imageio.ImageIO.createImageOutputStream(
          output);

      // Find den rigtige image-encoder, fx. en jpeg-encoder
      ImageWriter writer = null;
      Iterator writers = ImageIO.getImageWritersByFormatName("jpg");

      if (writers.hasNext())
        writer = (ImageWriter) writers.next();
      else
        return false;

      // Fortæl encoderen hvortil den skal skrive
      writer.setOutput(imgOut);

      // Sæt komprimeringskvaliteten
      ImageWriteParam param = writer.getDefaultWriteParam();
      param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
      param.setCompressionQuality(quality);

      // Skriv billedet til den underliggende stream
      writer.write(null, new IIOImage(img, null, null), param);
      imgOut.flush();
      writer.dispose();
      imgOut.close();

      return true;
    }
    catch (Exception e)
    {
      e.printStackTrace();
      return false;
    }
  }


Og scale-metoden:

public static BufferedImage scaleImage(BufferedImage img, float factor)
{
  int newWidth = (int)(img.getWidth() * factor);
  int newHeight = (int)(img.getHeight() * factor);
  BufferedImage newImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);

  AffineTransform af = new AffineTransform();
  af.scale(factor, factor);
  Graphics2D gfx = newImage.createGraphics();
  gfx.setTransform(af);
  gfx.drawImage(img, 0, 0, null);
  gfx.dispose();

  return newImage;
}
Avatar billede backupmand Nybegynder
09. november 2004 - 20:01 #3
Jeg har i mellemtiden fået loadet et billede fra en url og fået reduceret filstørrelsen drastisk. Jeg brugte bla. JAI (Java Advanced Imaging).

Min egen metode understøtter png, det gør denne ikke.
Dine metoder reducerer dog filstørrelsen kraftigt og det er godt. Farverne ser dog
lidt sjove ud i det endelige billede.

Prøv at loade flg billede ind fra den url via JAI:
        url = new URL("http://www.trafikken.dk/webcam/webcam1.jpg");
    RenderedOp image = JAI.create("url", url);
    BufferedImage bi=image.getAsBufferedImage();

prøv så at kalde dine metoder med flg paramettre:

BufferedImage newImage=scaleImage(bi,0.5f); // for en skalering der svarer til det halve (det er det jeg skal bruge)
saveImageAsJPG(newImage, "testimage", "C:", 0.5f);
Jeg har prøvet forskellige parametre i den sidste metode.

Hvis du vil, så prøv min metode:

public class imageprocessor {

    public static void main(String[] args) {
    URL url;
    try {
        url = new URL("http://www.trafikken.dk/webcam/webcam1.jpg");
        RenderedImage image = JAI.create("url", url);
        Vector sources=new Vector();
        sources.addElement(image);
        RenderableImage r = new MultiResolutionRenderableImage(sources,0.3F,0.3F,1.0F);
       
        // scaling
        float edgeLength=50.0F;
        int height=100;
        int width=100;
        boolean tall = (height > width);
          float modifier = edgeLength / (float) (tall ? height : width);
          ParameterBlock params = new ParameterBlock();
          params.addSource(image);
          params.add(modifier);//x scale factor
          params.add(modifier);//y scale factor
          params.add(0.0F);//x translate
          params.add(0.0F);//y translate
          params.add(new InterpolationNearest());//interpolation method
          RenderedOp result = JAI.create("scale", params);
         
              ColorCube colorMap=ColorCube.BYTE_496;
                  KernelJAI[] ditherMask = KernelJAI.DITHER_MASK_443;

              ParameterBlock pb = new ParameterBlock();
          pb.addSource(result).add(colorMap).add(ditherMask);
           
        ColorModel cm=result.getColorModel();
        ImageLayout layout = new ImageLayout();
        layout.setTileWidth(100).setTileHeight(100);
        layout.setColorModel(cm);
       
                RenderingHints rh = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout);
       
            PlanarImage img= (PlanarImage)JAI.create("ordereddither",pb);
                                                         
        String filename = "C:/importedpic.png";
        String format = "PNG";       
          RenderedOp opImage = JAI.create("filestore", img,filename, format);
       
    } catch (MalformedURLException e) {       
        System.out.println(e.getMessage());
        e.printStackTrace();
    }   
    }
}

Dit billede fylder mindre, men er meget rødt og mørkt...
Avatar billede backupmand Nybegynder
09. november 2004 - 20:03 #4
NB der er nogle ting jeg ikke bruger deroppe, idet jeg har forsøgt nogle forskellige ting.
Avatar billede mikkelbm Nybegynder
09. november 2004 - 20:14 #5
Nu har jeg ikke før prøvet at rode med JAI, og jeg har det heller ikke på min maskine, så jeg kan ikke teste.
Mine metoder har ikke voldt mig problemer før. Men det var også mere som inspiration.

JAI kan jeg desværre ikke hjælpe med.
Avatar billede backupmand Nybegynder
09. november 2004 - 20:20 #6
OK, det er iorden ... men har det lykkedes dig at få skaleret et jpg billede så, det ser samtidig pænt ud det endelige billede?`
Avatar billede mikkelbm Nybegynder
09. november 2004 - 20:41 #7
Hmmm... Har lige testet metoden, og det ser ud til at du har ret. Det er bare underligt, for jeg er sikker på at det har virket før.
Avatar billede mikkelbm Nybegynder
09. november 2004 - 20:46 #8
Så kan jeg desværre slet ikke hjælpe :(
Avatar billede backupmand Nybegynder
09. november 2004 - 21:32 #9
Tak for hjælpen, jeg fordeler dog pointene mellem os. Hvis du vil give et svar også.
Avatar billede mikkelbm Nybegynder
09. november 2004 - 21:34 #10
Ok.

Men du skal jo kun acceptere mit svar, hvis du kunne bruge det til noget.
Avatar billede backupmand Nybegynder
09. november 2004 - 22:48 #11
Det er helt iorden. Vi deler disse point.
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester