/ Forside / Teknologi / Udvikling / Java / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Java
#NavnPoint
molokyle 3688
Klaudi 855
strarup 740
Forvirret 660
gøgeungen 500
Teil 373
Stouenberg 360
vnc 360
pmbruun 341
10  mccracken 320
com.sun.image.codec.jpeg
Fra : Andreas Andersen


Dato : 26-07-05 21:32

Hej,

jeg skal bruge noget kode til at skalere nogle jpg-billeder ned. Jeg har
søgt lidt på nettet og stumpet nedenstående sammen. Det virker fint nok, men
billederne bliver ikke den kvalitet jeg kunne ønske mig - jeg kan selv få
det til at se væsentligt bedre ud ved at skalere med paintshop eller
lignende. Jeg har sat kvaliteten til maks., men det nytter ikke noget. Er
der nogen der har nogle forslag eller kender en anden java-pakke der er
bedre?

public static void resizeImage(String filename, int maxDim) {
try {

Image inImage = new ImageIcon(
filename).getImage();

double scale = (double)maxDim/(double)inImage.getHeight(null);
if (inImage.getWidth(null) > inImage.getHeight(null)) {
scale = (double)maxDim/(double)inImage.getWidth(null);
}

int scaledW = (int)(scale*inImage.getWidth(null));
int scaledH = (int)(scale*inImage.getHeight(null));

BufferedImage outImage = new BufferedImage(scaledW, scaledH,
BufferedImage.TYPE_INT_RGB);

AffineTransform tx = new AffineTransform();

tx.scale(scale, scale);

Graphics2D g2d = outImage.createGraphics();
g2d.drawImage(inImage, tx, null);
g2d.dispose();

OutputStream os = new FileOutputStream(filename);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(outImage);
param.setQuality(1, false);
encoder.encode(outImage, param);
os.close();
} catch (Exception e) { e.printStackTrace(); }
}

Mvh
Andreas



 
 
Arne Vajhøj (26-07-2005)
Kommentar
Fra : Arne Vajhøj


Dato : 26-07-05 21:51

Andreas Andersen wrote:
> jeg skal bruge noget kode til at skalere nogle jpg-billeder ned. Jeg har
> søgt lidt på nettet og stumpet nedenstående sammen. Det virker fint nok, men
> billederne bliver ikke den kvalitet jeg kunne ønske mig -

1) du behøver ikke bruge com.sun.image.codec.jpeg i nyere
java versioner (der er javax.imageio pakkerne)

2) men jeg formoder at "ulykkerne" sker i skaleringen (som er
AWT kode) og ikke ikke ved skrivningen

3) så vidt jeg ved er image skalering ikke lige til, men
jeg har ikke know how til at komme med forslag til
alternative måder at gøre det på

4) googling finder bl.a.:
http://www.rgagnon.com/javadetails/java-0243.html
http://www.jguru.com/faq/view.jsp?EID=98950
som har 2 andre måder at gøre det på (men jeg har ingen
anelse om de er bedre end den du bruger)

Arne

Janus (27-07-2005)
Kommentar
Fra : Janus


Dato : 27-07-05 02:07

Andreas Andersen wrote:
> Hej,
>
> jeg skal bruge noget kode til at skalere nogle jpg-billeder ned. Jeg har
> søgt lidt på nettet og stumpet nedenstående sammen.

Tro mig.. du er ikke den eneste der har siddet og kæmpet en brav kamp
med skalering. Jeg lavede engang et site, hvor man kunne uploade
billeder og ville i den sammenhæng lave thumbnails. Det blev til en gang
mudder, lige meget hvor meget ANTI_ALIAS osv osv jeg forsøgte mig med.
Og for det ikke skulle være løgn, mener jeg også at de thumbnails jeg
producerede fyldte 10% mere end dem jeg kunne lave i mspaint :)

Jeg kunne også rigtig godt tænke mig at finde ud af, hvordan man
egentlig gør den slags. Bare det med at sætte størrelsen på billedet ned
og så i en stream til en fil holder i hvert fald ikke.

Vh Janus

--
Kids, try this at home: http://www.legendsrpg.net/index.php?refid=799

Thomas Bendsen (27-07-2005)
Kommentar
Fra : Thomas Bendsen


Dato : 27-07-05 06:56

Janus wrote:
> Andreas Andersen wrote:
>
>> Hej,
>>
>> jeg skal bruge noget kode til at skalere nogle jpg-billeder ned. Jeg
>> har søgt lidt på nettet og stumpet nedenstående sammen.

Jeg synes ikke problemet var så stort da jeg skulle skalere 2MP billeder
til 640x480, men da jeg så fik et 7MP kamera blev resultatet ofte
uacceptabelt.
Den løsning jeg har fundet er desværre temmelig langsom, men den hjælper
væsentligt på resultatet. Jeg "blurrer" simpelthen billedet inden
skaleringen. Dette kan gøre ved hjælp af den klasse der hedder
ConvolveOp og en kernel der f.eks. ser ud som:
1/9 1/9 1/9
1/9 1/9 1/9
1/9 1/9 1/9
størrelsen af denne kernel skal nogenlunde modsvare skaleringen. Denne
kernel svarer altså til at man skalerer med en faktor 3.

Men som sagt er det desværre meget langsomt.

Med venlig hilsen
Thomas Bendsen

Thomas Bendsen (27-07-2005)
Kommentar
Fra : Thomas Bendsen


Dato : 27-07-05 07:55

Janus wrote:
>
> Tro mig.. du er ikke den eneste der har siddet og kæmpet en brav kamp
> med skalering. Jeg lavede engang et site, hvor man kunne uploade
> billeder og ville i den sammenhæng lave thumbnails. Det blev til en gang
> mudder, lige meget hvor meget ANTI_ALIAS osv osv jeg forsøgte mig med.
> Og for det ikke skulle være løgn, mener jeg også at de thumbnails jeg
> producerede fyldte 10% mere end dem jeg kunne lave i mspaint :)
>
> Jeg kunne også rigtig godt tænke mig at finde ud af, hvordan man
> egentlig gør den slags. Bare det med at sætte størrelsen på billedet ned
> og så i en stream til en fil holder i hvert fald ikke.
>
> Vh Janus
>

Hej Janus

Hvis det er digitale fotos du taler om, er du så opmærksom på muligheden
for at hive en thumbnail direkte ud af Exif data. Dette kan gøres ved
hjælp af en bibliotek lavet af en der hedder Drew Noakes. Du kan hente
biblioteket her:
http://www.drewnoakes.com/code/exif/
Dette er under alle omstændigheder meget hurtigere end at begynde at
indlæse hele billedet og derefter skalere.

Med venlig hilsen
Thomas Bendsen

Janus (27-07-2005)
Kommentar
Fra : Janus


Dato : 27-07-05 12:56

Thomas Bendsen wrote:

>
> Hvis det er digitale fotos du taler om, er du så opmærksom på muligheden
> for at hive en thumbnail direkte ud af Exif data. Dette kan gøres ved
> hjælp af en bibliotek lavet af en der hedder Drew Noakes. Du kan hente
> biblioteket her:
> http://www.drewnoakes.com/code/exif/
> Dette er under alle omstændigheder meget hurtigere end at begynde at
> indlæse hele billedet og derefter skalere.
>
> Med venlig hilsen
> Thomas Bendsen

Hej Thomas!
Tak for sit svar, og ja, i dette tilfælde var det decideret Thumbnails
jeg ville ha'. Men ser du, det tager jo lidt det sjove fra projektet,
hvis man man hapser tommelfingerneglen fra meta data :) Jeg synes det er
sjovt selv at sidde og rode med det:

public class ThumbNail {

   public static void main(String[] args) {
      new ThumbNail("test.jpg", 0.40d);
   }
   
   public ThumbNail(String picName, double scale) {
      Toolkit tool = Toolkit.getDefaultToolkit();
      MediaTracker mTrack = new MediaTracker(new Container());
      Image image = tool.getImage(picName);
      mTrack.addImage(image, 0);
      try {
         mTrack.waitForID(0);
      }
      catch (InterruptedException e) {
      }
      int xThumbSize = (int)(image.getWidth(null) * scale);
      int yThumbSize = (int)(image.getHeight(null) * scale);
      
      BufferedImage thumbImage = new BufferedImage(xThumbSize,
            yThumbSize, BufferedImage.TYPE_INT_RGB);
          Graphics2D g2d = thumbImage.createGraphics();
          g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
          RenderingHints.VALUE_INTERPOLATION_BILINEAR);
          g2d.drawImage(image, 0, 0, xThumbSize, yThumbSize, null);
      try {
         ImageIO.write(thumbImage, "JPG", new File("thumb"+picName));
      }
      catch (IOException ioe) {
         ioe.printStackTrace();
      }
   }
}

Af uransagelige årsager ser dette her ud til at generere ganske
udmærkede Thumbnails.

VH Janus



--
Kids, try this at home: http://www.legendsrpg.net/index.php?refid=799

Thomas Bendsen (27-07-2005)
Kommentar
Fra : Thomas Bendsen


Dato : 27-07-05 13:52

Janus wrote:
> public class ThumbNail {
>
> public static void main(String[] args) {
> new ThumbNail("test.jpg", 0.40d);
> }
>
> public ThumbNail(String picName, double scale) {
> Toolkit tool = Toolkit.getDefaultToolkit();
> MediaTracker mTrack = new MediaTracker(new Container());
> Image image = tool.getImage(picName);
> mTrack.addImage(image, 0);
> try {
> mTrack.waitForID(0);
> }
> catch (InterruptedException e) {
> }
> int xThumbSize = (int)(image.getWidth(null) * scale);
> int yThumbSize = (int)(image.getHeight(null) * scale);
>
> BufferedImage thumbImage = new BufferedImage(xThumbSize,
> yThumbSize, BufferedImage.TYPE_INT_RGB);
> Graphics2D g2d = thumbImage.createGraphics();
> g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
> RenderingHints.VALUE_INTERPOLATION_BILINEAR);
> g2d.drawImage(image, 0, 0, xThumbSize, yThumbSize, null);
> try {
> ImageIO.write(thumbImage, "JPG", new File("thumb"+picName));
> }
> catch (IOException ioe) {
> ioe.printStackTrace();
> }
> }
> }
>
> Af uransagelige årsager ser dette her ud til at generere ganske
> udmærkede Thumbnails.
>
> VH Janus
Hej Janus

Har du prøvet at sammenligne dette med skalering ved hjælp af
AffineTransform? Jeg synes ikke umiddelbart der er den store forskel.
Ved en skaleringsfaktor på 0,4 har jeg generelt ikke de store problemer.
Det er først ved kraftigere skaleringer at det bliver grimt.

Under alle omstændigheder slipper du jo ikke for den relativt
tidskrævende proces med at indlæse hele billedet, og når man skal vise
mere end 50 thumbnails så er det altså en stor fordel blot at indlæse et
par kB pr billede.

Med venlig hilsen
Thomas


Janus (27-07-2005)
Kommentar
Fra : Janus


Dato : 27-07-05 14:20

Thomas Bendsen wrote:

>
> Hej Janus
>
> Har du prøvet at sammenligne dette med skalering ved hjælp af
> AffineTransform? Jeg synes ikke umiddelbart der er den store forskel.
> Ved en skaleringsfaktor på 0,4 har jeg generelt ikke de store problemer.
> Det er først ved kraftigere skaleringer at det bliver grimt.
>
> Under alle omstændigheder slipper du jo ikke for den relativt
> tidskrævende proces med at indlæse hele billedet, og når man skal vise
> mere end 50 thumbnails så er det altså en stor fordel blot at indlæse et
> par kB pr billede.
>
> Med venlig hilsen
> Thomas
>

Ventetiden er ligemeget, det er jo mest af alt bare for et
for-sjov-projekt, du ved... "fordi jeg kan".
Jeg har sammenlignet de 2 outputs med en 1:10 skalering, AffineTransform
er pænest, men fylder så også 3 gange så meget (2.07kb vs 6.76kb).

Det jeg så har fået ud af dette lille projekt er eksempelvis kendskabet
til AffineTransform. Har aldrig før kigget på java.awt.geom pakken. Jeg
må så nok også lige indrømme, at jeg ikke helt har forstået hvad
AffineTransform bruges til?

Vh Janus


--
Kids, try this at home: http://www.legendsrpg.net/index.php?refid=799

Janus (27-07-2005)
Kommentar
Fra : Janus


Dato : 27-07-05 14:29

Janus wrote:
> Thomas Bendsen wrote:
>
>>
>> Hej Janus
>>
>> Har du prøvet at sammenligne dette med skalering ved hjælp af
>> AffineTransform? Jeg synes ikke umiddelbart der er den store forskel.
>> Ved en skaleringsfaktor på 0,4 har jeg generelt ikke de store
>> problemer. Det er først ved kraftigere skaleringer at det bliver grimt.
>>
>> Under alle omstændigheder slipper du jo ikke for den relativt
>> tidskrævende proces med at indlæse hele billedet, og når man skal vise
>> mere end 50 thumbnails så er det altså en stor fordel blot at indlæse
>> et par kB pr billede.
>>
>> Med venlig hilsen
>> Thomas
>>
>
> Ventetiden er ligemeget, det er jo mest af alt bare for et
> for-sjov-projekt, du ved... "fordi jeg kan".
> Jeg har sammenlignet de 2 outputs med en 1:10 skalering, AffineTransform
> er pænest, men fylder så også 3 gange så meget (2.07kb vs 6.76kb).
>
> Det jeg så har fået ud af dette lille projekt er eksempelvis kendskabet
> til AffineTransform. Har aldrig før kigget på java.awt.geom pakken. Jeg
> må så nok også lige indrømme, at jeg ikke helt har forstået hvad
> AffineTransform bruges til?
>
> Vh Janus
>
>

Well, når jeg har læst denne introduktion (som for øvrigt er MEGET
imponerende!), har jeg nok fået lidt mere idé om tingene... jeg sidder
og får helt lyst til at lave en flysimulator! :)

Men Thomas, du må stadig meget gerne komme med en forklaring, hvis du
har lyst? Det er jo altid rart med input fra forskellige sider.

Vh Janus

--
Kids, try this at home: http://www.legendsrpg.net/index.php?refid=799

Janus (27-07-2005)
Kommentar
Fra : Janus


Dato : 27-07-05 14:33

Janus wrote:

>
> Well, når jeg har læst denne introduktion (som for øvrigt er MEGET
> imponerende!), har jeg nok fået lidt mere idé om tingene... jeg sidder
> og får helt lyst til at lave en flysimulator! :)
>
> Men Thomas, du må stadig meget gerne komme med en forklaring, hvis du
> har lyst? Det er jo altid rart med input fra forskellige sider.
>
> Vh Janus
>

Og så lige et link ... (*doh!*)
http://www.glyphic.com/transform/plugin/1intro.html

--
Kids, try this at home: http://www.legendsrpg.net/index.php?refid=799

Thomas Bendsen (27-07-2005)
Kommentar
Fra : Thomas Bendsen


Dato : 27-07-05 16:07

Janus wrote:
> Thomas Bendsen wrote:
>
>>
>> Hej Janus
>>
>> Har du prøvet at sammenligne dette med skalering ved hjælp af
>> AffineTransform? Jeg synes ikke umiddelbart der er den store forskel.
>> Ved en skaleringsfaktor på 0,4 har jeg generelt ikke de store
>> problemer. Det er først ved kraftigere skaleringer at det bliver grimt.
>>
>> Under alle omstændigheder slipper du jo ikke for den relativt
>> tidskrævende proces med at indlæse hele billedet, og når man skal vise
>> mere end 50 thumbnails så er det altså en stor fordel blot at indlæse
>> et par kB pr billede.
>>
>> Med venlig hilsen
>> Thomas
>>
>
> Ventetiden er ligemeget, det er jo mest af alt bare for et
> for-sjov-projekt, du ved... "fordi jeg kan".
> Jeg har sammenlignet de 2 outputs med en 1:10 skalering, AffineTransform
> er pænest, men fylder så også 3 gange så meget (2.07kb vs 6.76kb).
>
> Det jeg så har fået ud af dette lille projekt er eksempelvis kendskabet
> til AffineTransform. Har aldrig før kigget på java.awt.geom pakken. Jeg
> må så nok også lige indrømme, at jeg ikke helt har forstået hvad
> AffineTransform bruges til?
>
> Vh Janus
>
>


Hej Janus

Det er altid fedt at lære noget nyt. Med hensyn til størrelsen kan du
faktisk selv styre komprimeringen af JPG-filen. Følgende kode har jeg
hugget et eller andet sted, så du må ikke bede mig forklare alle
detaljer, men det virker.
private static void compressJpegFile(RenderedImage image, File outfile,
float compressionQuality) throws IOException{
   // Retrieve jpg image to be compressed
   RenderedImage rendImage = image;

// Find a jpeg writer
ImageWriter writer = null;
Iterator iter = ImageIO.getImageWritersByFormatName("jpg");
if (iter.hasNext()) {
writer = (ImageWriter)iter.next();
}

// Prepare output file
ImageOutputStream ios
=imageIO.createImageOutputStream(outfile);
writer.setOutput(ios);

// Set the compression quality
ImageWriteParam iwparam = new
JPEGImageWriteParam(Locale.getDefault());
iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT) ;
iwparam.setCompressionQuality(compressionQuality);

// Write the image
writer.write(null, new IIOImage(rendImage, null, null), iwparam)
// Cleanup
ios.flush();
writer.dispose();
ios.close();
}


Med hensyn til AffineTransform så er den simple forklaring nok at den
kan bruges at skalere, rotere og flytte et koordinatsystem. Hvis du er
lidt matematisk funderet er den korrekte forklaring at punkterne i dit
koordinatsystem kan betragtes som vektorer, og en AffineTransform
foretager så en vektoraddition og matrixmultiplikation.
I øvrigt kan du læse mere i min foretrukne kilde til javainformation:
http://java.sun.com/docs/books/tutorial/2d/display/transforming.html

Med venlig hilsen
Thomas Bendsen

Janus (27-07-2005)
Kommentar
Fra : Janus


Dato : 27-07-05 17:40

Thomas Bendsen wrote:

>
>
> Med hensyn til AffineTransform så er den simple forklaring nok at den
> kan bruges at skalere, rotere og flytte et koordinatsystem. Hvis du er
> lidt matematisk funderet er den korrekte forklaring at punkterne i dit
> koordinatsystem kan betragtes som vektorer, og en AffineTransform
> foretager så en vektoraddition og matrixmultiplikation.
> I øvrigt kan du læse mere i min foretrukne kilde til javainformation:
> http://java.sun.com/docs/books/tutorial/2d/display/transforming.html
>
> Med venlig hilsen
> Thomas Bendsen

Ja, det burde jeg vel være jf. mit datalogistudie :) Well, det er godt
nok længe siden jeg har været der...

--
Kids, try this at home: http://www.legendsrpg.net/index.php?refid=799

Ruben Hesselbæk (27-07-2005)
Kommentar
Fra : Ruben Hesselbæk


Dato : 27-07-05 11:53

Andreas Andersen wrote:
> Hej,
>
> jeg skal bruge noget kode til at skalere nogle jpg-billeder ned. Jeg har
> søgt lidt på nettet og stumpet nedenstående sammen. Det virker fint nok, men
> billederne bliver ikke den kvalitet jeg kunne ønske mig - jeg kan selv få
> det til at se væsentligt bedre ud ved at skalere med paintshop eller
> lignende. Jeg har sat kvaliteten til maks., men det nytter ikke noget. Er
> der nogen der har nogle forslag eller kender en anden java-pakke der er
> bedre?
>
----snip----

Har du prøvet JAI ?

http://java.sun.com/products/java-media/jai/iio.html

/Ruben

Andreas Andersen (27-07-2005)
Kommentar
Fra : Andreas Andersen


Dato : 27-07-05 15:58

Hej,

mange tak for alle svarene! Jeg sad og søgte på nogle af de ting I har
foreslået, da jeg faldt over metoden Image.getScaledInstance, som man kan
bruge med forskellige kvalitetsparametre. Hvis man bruger Image.SCALE_SMOOTH
og Image.SCALE_AREA_AVERAGING bliver billederne meget pænere med bløde
kanter. Hvis nogen skulle være interesseret er min modificerede kode
nedenfor.

Mvh
Andreas

public static void resizeImage(String filename, int maxDim) {
try {
Image outImage;
Image inImage = new ImageIcon(filename).getImage();
double scale = (double)maxDim/(double)inImage.getHeight(null);
if (inImage.getWidth(null) > inImage.getHeight(null)) {
scale = (double)maxDim/(double)inImage.getWidth(null);
}

int scaledW = (int)(scale*inImage.getWidth(null));
int scaledH = (int)(scale*inImage.getHeight(null));
BufferedImage tempImage = new BufferedImage(inImage.getWidth(null),
inImage.getHeight(null), BufferedImage.TYPE_INT_RGB);
BufferedImage finalImage = new BufferedImage(scaledW, scaledH,
BufferedImage.TYPE_INT_RGB);

Graphics2D g2d = tempImage.createGraphics();
g2d.drawImage(inImage, null, null);
g2d.dispose();

outImage = tempImage.getScaledInstance(scaledW, scaledH,
Image.SCALE_SMOOTH | Image.SCALE_AREA_AVERAGING);

g2d = finalImage.createGraphics();
g2d.drawImage(outImage, null, null);
g2d.dispose();

OutputStream os = new FileOutputStream(filename);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(finalImage);
param.setQuality((float) 0.75, false);
encoder.encode(finalImage, param);
os.close();
} catch (Exception e) { e.printStackTrace(); }
}



Søg
Reklame
Statistik
Spørgsmål : 177438
Tips : 31962
Nyheder : 719565
Indlæg : 6408041
Brugere : 218879

Månedens bedste
Årets bedste
Sidste års bedste