/ 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
JPEGencode, imagestørrelse
Fra : Allan Unnerup


Dato : 14-06-02 13:19

Hvordan kan jeg se størelsen af et encoded image?

JPEGEncodeParam prm = encoder.getDefaultJPEGEncodeParam(outImage);
prm.setQuality(0.5f, false);
encoder.setJPEGEncodeParam(prm);
encoder.encode(outImage);

Og nu vil jeg gerne vide, hvor mange bytes det komprimerede billede fylder.
Hvis billedet fylder for meget, skal det nemlig komprimeres yderligere.

prm.setQuality(0.3f, false);
encoder.setJPEGEncodeParam(prm);
encoder.encode(outImage);

Med venlig hilsen
Allan




 
 
Dennis Thrysøe (14-06-2002)
Kommentar
Fra : Dennis Thrysøe


Dato : 14-06-02 13:23



Allan Unnerup wrote:
> Hvordan kan jeg se størelsen af et encoded image?
>
> JPEGEncodeParam prm = encoder.getDefaultJPEGEncodeParam(outImage);
> prm.setQuality(0.5f, false);
> encoder.setJPEGEncodeParam(prm);
> encoder.encode(outImage);

Hvad returnerer denne metode? Eller hvad er outImage?

Du må kunne få fingerene i en OutputStream eller lign.?

-dennis


Allan Unnerup (14-06-2002)
Kommentar
Fra : Allan Unnerup


Dato : 14-06-02 14:08

> Hvad returnerer denne metode? Eller hvad er outImage?
>
> Du må kunne få fingerene i en OutputStream eller lign.?

O.k. her er lidt udvidet kode:

BufferedImage outImage = <et billede>

FileOutputStream fout = new FileOutputStream(<filnavn>);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(fout);

// Komprimering
JPEGEncodeParam prm = encoder.getDefaultJPEGEncodeParam(outImage);
prm.setQuality(0.5f, false);
encoder.setJPEGEncodeParam(prm);

encoder.encode(outImage);
fout.close();

Jeg kan selvfølgelig se størrelsen af den resulterende fil på disken, men
der er jo ingen grund til at skrive filen på disken, hvis den skal
komprimeres yderligere.

Det, jeg egentlig helst vil, er at komprimere billedet, uden at skrive det
til en fil,
rekomprimere det, hvis det er for stort, og først skrive billedet til en
fil, når størrelsen er passende.

Med venlig hilsen
Allan




Dennis Thrysøe (14-06-2002)
Kommentar
Fra : Dennis Thrysøe


Dato : 14-06-02 14:16

Allan Unnerup wrote:
>>Hvad returnerer denne metode? Eller hvad er outImage?
>>
>>Du må kunne få fingerene i en OutputStream eller lign.?
>
>
> O.k. her er lidt udvidet kode:
>
> BufferedImage outImage = <et billede>
>
> FileOutputStream fout = new FileOutputStream(<filnavn>);
> JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(fout);
>
> // Komprimering
> JPEGEncodeParam prm = encoder.getDefaultJPEGEncodeParam(outImage);
> prm.setQuality(0.5f, false);
> encoder.setJPEGEncodeParam(prm);
>
> encoder.encode(outImage);
> fout.close();
>
> Jeg kan selvfølgelig se størrelsen af den resulterende fil på disken, men
> der er jo ingen grund til at skrive filen på disken, hvis den skal
> komprimeres yderligere.
>
> Det, jeg egentlig helst vil, er at komprimere billedet, uden at
skrive det
> til en fil,
> rekomprimere det, hvis det er for stort, og først skrive billedet til en
> fil, når størrelsen er passende.

Jeg ved ikke hvordan JPEGImageEncoder virker på dette punkt (og det gør
mange andre vist heller ikke - den er vistnok hverken dokumenteret eller
supporteret). Men hvis ikke den har en feature hvor man kan lse
størrelsen direkte, så kunne de hælde resultatet over i en
ByteArrayOutputStream og kalde size() på den.


-dennis


Allan Unnerup (21-06-2002)
Kommentar
Fra : Allan Unnerup


Dato : 21-06-02 15:39


> Jeg ved ikke hvordan JPEGImageEncoder virker på dette punkt (og det gør
> mange andre vist heller ikke - den er vistnok hverken dokumenteret eller
> supporteret). Men hvis ikke den har en feature hvor man kan lse
> størrelsen direkte, så kunne de hælde resultatet over i en
> ByteArrayOutputStream og kalde size() på den.

Det virker fint, tak skal du have.

Med venlig hilsen
Allan



Niels Ull Harremoës (24-06-2002)
Kommentar
Fra : Niels Ull Harremoës


Dato : 24-06-02 22:14

Hej Allan!

Ulempen ved en ByteArrayOutputStream er at du bruger tid og hukommelse på at
komprimere hele billedet, selvom du så alligevel smider det væk.
Evt kunne du lave en OutputStreamWithMaxSize extends FilterOutputStream, som
hele tiden holdt øje med størrelsen og smed en exception, hvis den overskred
en bestemt grænse? Fx (ej testet)

public class OutputStreamWithMaxSize extends FilterOutputStream {

public static class StreamTooLargeException extends IOException {
public StreamTooLargeException(String s) { super(s); }
};

public OutputStreamWithMaxSize(OutputStream out, long maxSize) {
super(out);
this.maxSize = maxSize;
}
private long byteCount = 0;
private final long maxSize;

public void write(byte[] b] throws IOException {
addBytes(b.length);
super.write(b);
}
public void write(byte[] b, int off, int len) throws IOException {
addBytes(len);
super.write(b, off, len);
}

public void write(int i) throws IOException {
addBytes(1);
super.write(i);
}

protected void addBytes(int n) throws StreamTooLargeException {
byteCount += n;
if (byteCount > maxSize) {
super.close();
throw new StreamTooLargeException("Stream can be at most " + maxSize
+ " bytes");
};
}
}


Hvis det går godt, er alt vel - ellers må du prøve igen. Men i det mindste
har du ikke fået din harddisk fyldt op af en 70 Gb fil, og du behøver ikke
spilde tid på at komprimere resten af billedet.

Fx

float quality = 0.5f;
boolean ok;
do {
OutputStreamWithMaxSize outStream = new OutputStreamWithMaxSize(new
FileOutputStream(filename), FILEMAXSIZE);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outStream);
try {// Komprimering
JPEGEncodeParam prm = encoder.getDefaultJPEGEncodeParam(outImage);
prm.setQuality(quality, false);
encoder.setJPEGEncodeParam(prm);
encoder.encode(outImage);
ok = true;
} catch(StreamTooLargeException ex) {
fout.close();
quality *= 0.5;
ok = false;
};
} while (!ok);

Ovenstående er ikke så kønt kodet, men du fatter forhåbentlig ideen.


"Allan Unnerup" <alu@udkik.dk> wrote in message
news:6UGQ8.77476$N46.2184564@news010.worldonline.dk...
>
> > Jeg ved ikke hvordan JPEGImageEncoder virker på dette punkt (og det gør
> > mange andre vist heller ikke - den er vistnok hverken dokumenteret eller
> > supporteret). Men hvis ikke den har en feature hvor man kan lse
> > størrelsen direkte, så kunne de hælde resultatet over i en
> > ByteArrayOutputStream og kalde size() på den.
>
> Det virker fint, tak skal du have.
>
> Med venlig hilsen
> Allan
>
>



Dennis Thrysøe (25-06-2002)
Kommentar
Fra : Dennis Thrysøe


Dato : 25-06-02 07:27

Niels Ull Harremoës wrote:
> Hej Allan!
>
> Ulempen ved en ByteArrayOutputStream er at du bruger tid og hukommelse på at
> komprimere hele billedet, selvom du så alligevel smider det væk.
> Evt kunne du lave en OutputStreamWithMaxSize extends FilterOutputStream, som
> hele tiden holdt øje med størrelsen og smed en exception, hvis den overskred
> en bestemt grænse? Fx (ej testet)

Det er bare (oftest) uheldigt, at bruge exceptions til denne form for
signallering og flow-kontrol.

Når der står 100 tråde med masser af requests og encoder jpegs på en
eller anden server, og den typisk skal forsøge med 5 forkerte størrelser
først - så koster det.

Men det er jo selvfølgelig heller ikke sikkert, at præmisserne er som
nævnt. Så kunne exceptions måske sagtens bruges.

Når alt kommer til alt handler del vel egentligt om, om man betraget et
for stort billede for en *rigtig* "excepitonal case".

-dennis


Niels Ull Harremoës (25-06-2002)
Kommentar
Fra : Niels Ull Harremoës


Dato : 25-06-02 11:59


"Dennis Thrysøe" <dt@netnord.dk> wrote in message
news:3D180D45.4030407@netnord.dk...
> > Evt kunne du lave en OutputStreamWithMaxSize extends FilterOutputStream,
som
> > hele tiden holdt øje med størrelsen og smed en exception, hvis den
overskred
> > en bestemt grænse? Fx (ej testet)
>
> Det er bare (oftest) uheldigt, at bruge exceptions til denne form for
> signallering og flow-kontrol.

Fra et skønhedsmæssigt synspunkt har du ret - men jeg kan ikke se andre
måder at gøre det på, hvis man ikke ønsker at spilde CPU tid på at encode
hele billedet, hvis det alligevel bliver for stort. Hvis man ikke smider en
exception, kan man jo ikke afbryde encode metoden, selvom det blot er
tidsspilde at kode billedet færdigt.

>
> Når der står 100 tråde med masser af requests og encoder jpegs på en
> eller anden server, og den typisk skal forsøge med 5 forkerte størrelser
> først - så koster det.

Jeps - men det kan man vel ikke rigtig gøre noget ved, hvis det er denne
funktionalitet, der ønskes? Med mit forslag sparer man dog en del CPU tid.

Man kan selvfølgelig nøjes med een baggrundstråd, og så en kø af billeder
til komprimering osv, såfremt det ikke er et krav at komprimeringen sker
synkront med et request.

> -dennis
>

Niels



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408925
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste