16. april 2006 - 12:22Der er
27 kommentarer og 2 løsninger
Billedscript, meget tung for hukommelsen
Jeg har et script hvor man, med et div, vælger hvilken del af billedet man gerne vil have som thumbnail. Der er to knapper, en Preview og en Save. Scriptet virker fint, men er temmeligt hukommelsestung. Findes der mere elegante måder at lave nedenstående på (billedet findes på serveren):
System.Drawing.Image B = Bitmap.FromFile(ImagePath); int PicWidth = B.Width; int PicHeight = B.Height; B.Dispose();
int MaxWidth = 500; int MaxHeight = 600;
//regn en scale factor, så billedet vises pænt på siden: double ScaleFactor = ImgTool.ImageScaler(MaxWidth,MaxHeight,PicWidth,PicHeight);
Det store billede, hvorpå man skal vælge en del, hentes med(koden er reduceret):
String FileName=Request.QueryString["FileName"].ToString(); int iWidth=int.Parse(Request.QueryString["w"].ToString()); int iHeight=int.Parse(Request.QueryString["h"].ToString()); }
System.Drawing.Image imgFullSize = System.Drawing.Image.FromFile(FileName); Bitmap bmNew = new Bitmap(iWidth, iHeight); Graphics g = Graphics.FromImage(bmNew);
Det er selvfølgeligt muligt at sætte kvaliteten ned på billederne, men er der andet der kan optimeres? (hellere et lidt langsommere script, end en outOfMemory exception)
Jeg ved ikke hvor meget hukommelse der bliver brugt på det, og jeg har ikke styr på hvor store billeder folk ligger op. Jeg kan selvfølgeligt bare afvise billeder der er for store, for har et eksempel på en der uploadede noget der var omkring 4000x5000px (!!!)
Ideen er lidt at jeg gerne ville kunne håndtere så store billeder hvis folk mener det er det de skal ligge op. Om det så er at konvertere den til et mindre billede først, og så arbejde med det, er ikke så vigtigt...
Det vil vel heller ikke hjælpe noget at bruge threads?
du må finde ud af hvad problemet er.... mit gæt ville være, at transporten af billederne til/fra klienten koster så mange gange mere tid, end den tid du bruger på serveren - så hvis du optimerer koden på serveren, vil det betyde meget lidt for brugeroplevelsen. men men ... det ville nok være en god idé hvis du prøvede at finde ud af hvor meget tid du bruger på billedbehandlingen. du kan ganske hurtigt finde ud af det ved et trace. hvis du vil finde ud af hvor meget memory du bruger - er det sikrest at benytte en profiler af en art.
eksempel på trace: // hvis du er i en page/kotrol-klasse Trace.Write("Starting imagemanipulation");
// andre steder fra HttpContext.Current.Trace.Write("Starting imagemanipulation");
du kan slå det til ved at sikre at du under <system.web> har sådan en her: <trace enabled="true" pageOutput="false"/>
du kan også få outputtet på hver side, ved at sætte pageOutput="true", men hvis du positionerer dine kontroller absolut bliver det lidt vanskeligt at læse (du kan jo prøve det).
nå men ... du kan så skrive tracemeddelelser ud når rutinen starter, og når den er færdig... så kan du se om tiden der bruges der overhovedet er værd at bekymre sig om i forhold til resten. trace.axd giver dig en fin præsentation af det, og du kan se nøjagtig hvor lang tid tingene tager mv.
Jeg prøver lige at genskabe den...det skal lige siges det var da der var en der prøvede med 4000x5000px billedet...så det er nok ikke så underlig, for det er jo et kæmpe billede...ville gerne ha at den bare tog længere tid end at komme med en mem exception...
Min stacktrace siger: at System.Drawing.Image.FromFile(String filename, Boolean useEmbeddedColorManagement) at System.Drawing.Image.FromFile(String filename)
Jeg kan ikke få den til at lave fejlen når den køres lokalt. Men dette er også et billede der fylder 1,44mb (3691x4829).
hmm... kan ikke lige se at der skulle være ballade... når du får fejlen - kan du så åbne filen med et almindeligt billedkiggerprogram (altså åbne den fil der ligger på serveren). mvh
Ja...kan jeg godt. Billedet bliver fint uploaded. Men selvom jeg bruger det samme billede, er det lidt forskelligt hvornår fejlen kommer. Nogen gange kommer den når jeg lige har uploaded den, og andre gange kommer den når jeg skal til at hente gennem outputstream...jeg prøver at lege lidt med at trace, og se om jeg kan finde et mønster...
System.Drawing.Image B = Bitmap.FromFile(ArtistImagesPath+Name); int PicWidth = B.Width; int PicHeight = B.Height; B.Dispose();
Er der andre måder? Jeg kikkede godt på den da jeg skrev den...det er lidt meget at hente hele billedet ind for at få størrelsen, men kender ikke andre metoder...
Hmm...Det virker meget som om at det simpelthen er størrelsen af billedet der sætter grænsen. Men kan man gøre andet end at bruge nogen try/catch og så give brugeren besked om at det ikke kan lade sig gøre?
Når først billederne bliver over en hvis størrelse, bliver systemet ustabilt, så man må vel selv bare skulle sætte et loft...Med mindre du har andre ideer?
der er en max-størrelse for den slags overførsler.... mener den er 4MB (så det kan den slags billeder jo hurtigt komme op på). hvor store skal de være før det kikser? mvh
Jeg har ikke fået den til at tage over 1,44mb, og det er egentligt lidt noget pis, men jeg skal igang med at forsøge mig lidt frem igen. Som sagt er tiden den bruger på det ikke så vigtigt som at undgå en fejl...Jeg vil prøve at evt gemme et midlertidigt billede som er mindre og arbejde på det i stedet for...
Pointsne er lige så meget fordi der er blevet brugt tid på det.
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.