Gå til innhold

[python] Les & skriv bitmap-filer (hjelp til forbedring)


Anbefalte innlegg

Hei. Jeg har et prosjekt på gang hvor jeg forsøker lese/skrive til bmp filer med kun python. Startet dette da jeg så PIL (pillow) som "overkill" for mange av mine prosjekter, noe mer lettvekt ble nødvendig (kan integreres i prosjekter).

Men, er beklageligvis ganske vanskelig å oppnå skikkelig hastighet slik modulen er nå. Bare det å laste printscreen bufferet fra windows in tar nesten 1 sekund (loope over alle pixelene kan da ikke være nødvendig?)... Åpne in en bitmap-fil er tilsvarnede tregt.

Så jeg spør etter tips, bedre fregangsmåter / det du kan tenke på som vil forbedre "modulen"... Tanken er at det skal fungerere på python >=2.7 og PyPy. Samt OS-uavhengig.

Slik er koden nå:
https://github.com/W...aster/bitmap.py

Det er en del som ikke fungerer enda, ikke alle bmp-headere virker til å bli lastet korrekt, evt. at råmaterialet (pixelene) ikke blir behandlet korrekt etter format. Har ikke noen erfaring med å jobbe med bitmaps - til nå har bare prøvd meg frem med Wikipeda som referanse.

__EDIT__:
Tester ut pythons array-klasse. I PyPy så økte dette hastigheten betraktelig, klarte å kjøre bmp.setPixel((x,y), bmp.getPixel(x,y)) over 4,000,000 iterasjoner på kun 220ms. Samme løsning var ikke like egnet i CPython (2.7)... hvor det tok hele 10 sekunder!
- Nok et område hvor PyPy er over 60 ganger raskere.

Med denne endringen kom det også en skokk andre endringer: Nå laster jeg bilder inn på millisekunder, og topper i noen tilfeller på rundt 30 millisekunder (alt etter bildestørrelse).

Problemet ved laste bufferet til en vanlig liste ligger i tiden det vil ta å iterere over alle pixelene: Det tar fort flere sekunder å bare lagre / lese inn filen. I motsetning til når jeg bruker arr = array('c', buffer) hvor det kun millisekunder.

Endret av warpie
Lenke til kommentar
Videoannonse
Annonse

For å gi et eksempel på hastighets fordel ved å bruke array forran liste:

import time as t
from array import array

X = 'l' * 10000000

# Create a ARRAY from string buffer
timer = t.time()
ARR = array('c', X)
print t.time()-timer

# Create a list from string buffer
timer = t.time()
LIST = list(X)
print t.time()-timer

# Create a list from string buffer (alternative)
timer = t.time()
list = [i for i in X]
print t.time()-timer

#---
CPython 2.7
>>> 7.22605770826 ms
>>> 165.468437672 ms
>>> 777.811088324 ms

PyPy 2.1:
>>> 14.2045789957 ms
>>> 1688.11790597 ms
>>> 1088.98761791 ms

Opprette en array av char ser ut til å være beste løsningen: 10 millioner inputs på 7-14 ms er relativt kjapt.. Python 2.7+ er UTROLIG treg på å hente UT verdier fra en array. hmm.gif

Endret av warpie
Lenke til kommentar

 

 


Jeg tror at grunnen til at det er tregt å lese fra et array.array i cpython er at hver gang du leser fra arrayet så må verdien gjøres om til et python object.

Hmm.. Det høres ikke så usansynlig ut.

PyPy oppførerer seg anderledes i forhold til det hele, men de har tross alt en helt annen struktur med jit kompilering. Endret av warpie
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...