FANDOM


Ambox importantEz a szócikk az érettségi követelményeket meghaladó ismeretet tartalmaz.

Az alábbi modul BMP képek előállítását teszi lehetővé, és az objektumok alkalmazását demonstrálja. Az utolsó két sor mutatja, miként lehet eldönteni, hogy a modult önálló programként indítottuk-e el vagy egy másik programba importálva. Az előbbi esetben egy egyszerű demót futtat. A második használatra az Érettségi idegen nyelven, 2010 tavasz (Telek) szócikk mutat példát, ahol – a kötelező feladat megoldásán túl – a bitmap osztály egy példányát létrehozva rajzoljuk meg Patakfalva új lakónegyedét. Ugyanerre példa a második szakaszban a bitmap-demo.py, amely nem új képet hoz létre, hanem a bitmap.py demóját módosítja. Ez egy példa a külső hozzáférésre az osztályban definiált változókhoz.

Check Tesztelve a 3.1.2 verzióban. (A 2.x verzió elérhető a laptörténetben.) 3.4-ben is működik!:)

# -*- coding: utf-8 -*-

"""
Ez a modul egy 8 bites színmélységű, tömörítetlen BMP-képet állít elő.
Aki nem hiszi, járjon utána a specifikációnak!

(C) Perselus, all lefts reserved, egyébként meg lent van a lap alján a licenc.
    Use it as is, at your own risk, blahblahblah.
    http://hu.sulipython.wikia.com/wiki/bitmap.py

Bemenő paraméterei:
-- picname: a létrehozandó file teljes neve (kiterjesztéssel és elérési úttal)
-- width, height: egészek, a kép szélessége és magassága
-- colornum: a ténylegesen használt színek száma (max. 256)
   Ha nem adod meg, 256 az alapértelmezés.
-- colors: egy 1024 számból álló lista a használni kívánt színekkel,
   az ajánlás szerint fontossági sorrendben (a modul mindegyik színt fontosnak
   jelöli).
   Minden szín 4 byte: B, G, R, 0. (FORDÍTOTT SORREND!)
-- bits: a képet leíró kétdimenziós lista, width*height byte terjedelemben.
   Minden pixelt 1 byte-on ír le, a szám a kívánt szín sorszáma a colors
   listában. A 0. byte a bal alsó sarok, utána halad jobbra, majd felfelé.
   A lista 0. eleme a 0. sort leíró width hosszúságú lista, és height elem van.

A filenév kivételével minden paraméter elhagyható, ilyenkor a modul beleír
valamit példa gyanánt. Bolondbiztos ellenőrzést nem végez, még a file létezésére
sem. Ha a legfontosabb képed nevét adod meg, és letörli, ne az én hibám legyen.

A tényleges kirajzolást az __init__ függvénybe is tehettem volna (így a kép
az osztály példányosításakor automatikusan mentődne). Azért került külön a 
rajzol() függvénybe, hogy a metódusok külső hívását bemutassa. Így viszont 
lehetővé vált, hogy az alapértelmezett értékekhez egy külső program hozzáférjen,
ezt használja ki a lenti bitmap-demo.py: nem rajzol teljesen új képet, hanem
ezt a demót módosítja.
"""


class bitmap():

    def __init__(self, picname, width=800, height=600,
                 colornum=0, colors=None, bits=None):
        #A self után vannak a kötelező paraméterek (itt csak a picname),
        #utána a nem kötelezőek valami alapértelmezett értékkel.
        #A hívó által megadott érték felülírja az alapértelmezettet!
        #Így adhatjuk át őket a metódusoknak:
        self.picname=picname
        self.width=width
        self.height=height
        self.colornum=colornum
        #Amelyiknek nincs kezdőértéke, annak adunk (a None hamisat ad):
        if not colors:
            colors=self.democolors()
        if not bits:
            bits=self.demobits()
        self.colors=colors
        self.bits=bits

    def rajzol(self):
        #És akkor a rajz:
        picture=self.draw()
        self.save(picture)

    def dec2hexlist(self,num,bytes):
        #A num számot bytes byte-on ábrázolja a legkisebb helyiértékűtől kezdve
        #Ilyen alakban várja őket a BMP.
        lista=[]
        for d in range(bytes):
            lista.append(num % 256)
            num//=256
        return lista

    def draw(self):
        #A colornum, és a colors paramétereket nem vesszük át lokális
        #változóba, ezért a self. előtaggal hivatkozhatunk rájuk.
        #A szélesség, a magasság és a bits viszont lokális változó lesz,
        #mert többször is használjuk őket.
        #Ugyanígy a dec2hexlist is -- figyeljük meg, hogy a függvény
        #nevét is ugyanúgy adhatjuk át, mint a változókét!
        
        width, height, bits = self.width, self.height, self.bits
        dec2hexlist=self.dec2hexlist

        #A sorok hosszát a méretben néggyel oszthatóra kell kiegészíteni,
        #különben ciklikusan eltolódik a kép, és bután néz ki.
        #A megjelenített sorok hosszát ez nem befolyásolja.
        #Minden sor végét fogjuk max. 3 db 0-val kiegészíteni.
        wid2=width
        while wid2 % 4:
            wid2+=1
        
        #Első 14 byte
        header1=[66,77]+dec2hexlist(wid2*height+1078,4)+[0,0,0,0,54,4,0,0]
        #Következő 40 byte
        header2=[40,0,0,0]+dec2hexlist(width,4)+dec2hexlist(height,4)
        header2+=[1,0,8,0]+[0]*4+dec2hexlist(wid2*height,4)+[0]*8
        header2+=dec2hexlist(self.colornum,4)+[0]*4

        #Ha a sorok hossza width, akkor kiegészítjük wid2-re nullákkal.
        #Egyéb ellenőrzés nincs, annyit nem ér az egész, ahányféleképpen
        #el lehet rontani. A gyorsaság kedvéért csak a 0. sor hosszát figyeljük.
        delta=wid2-len(bits[0])
        pixels=[]
        for sor in bits:
            for i in range(delta):
                sor.append(0)
            pixels+=sor
        s=bytearray()   #Megváltoztatható, 8 bites "karakterlánc"
        for c in header1+header2+self.colors+pixels:
            s.append(c)
        return s

    def save(self,picture):
        try:
            f=open(self.picname,'wb')
            f.write(picture)
            f.close()
        except IOError:
            print("Nem lehetett menteni.")
        
    def democolors(self):
        #Beír valamit az első hat színbe (BGR sorrend!), a többi fekete lesz.
        colors=[240,240,240,0, 0,0,0,0, 0,102,255,0,
                255,0,0,0 ,0,155,0,0, 255,100,255,0]
        colors+=[0,0,0,0]*250
        return colors

    def demobits(self):
        width=self.width
        height=self.height
        #Most jön a kép! A bal alsó sarokból jobbra, és soronként felfelé.
        #Minden pixel 1 byte, a kód a szín sorszáma a fenti táblában.
        #Legyen pl. 4 egyforma téglalap:
        bits=[]
        for i in range(height//2):
            sor=[0]*(width//2)+[4]*(width-width//2)
            bits.append(sor)
        for i in range(height-height//2):
            sor=[2]*(width//2)+[3]*(width-width//2)
            bits.append(sor)
        return bits

def demo():
    #Ez fut le, ha önálló programként akarja futtatni valaki.
    #Figyeljük meg, hogy ez már nem tartozik a bitmap osztályhoz,
    #mivel nincs behúzva.

    s="Írd be az elkészítendő BMP teljes nevét. Ha már van olyan, letörlődik!\n"
    file_neve=input(s)

    bmp=bitmap(file_neve)
    bmp.rajzol()

if __name__=='__main__':
    demo()

Egy alkalmazásSzerkesztés

Yes check Tesztelve a 2.5.1 verzióban. (Majdnem biztosan jó 3.1-ben is.) 2.7.6-ban nem működik.

#bitmap-demo.py
#Egyszerű demó: a bitmap.py-ban definiált ábra közepébe rajzoljunk kört.

#Nem az egész math modult importáljuk, csak a négyzetgyököt.
#Ezért névtér nélkül hivatkozhatunk majd rá.
from math import sqrt
import bitmap

rajz=bitmap.bitmap('demo.bmp')
#Átírjuk az 1. színt feketéről sárgára, az eredeti demó úgysem használta.
rajz.colors[4:8]=[0,255,255,0]
#Padlós osztással meghatározzuk a közepét (így egész szám marad).
cx=rajz.width//2
cy=rajz.height//2
r=100

#A körrajzolásnak létezik kifinomultabb módja is.
#Most egy befoglaló négyzetben keressük, melyik pont tartozik a körbe.
#Gyakorlati okból <r a feltétel,nem <=r, különben négy pixel lenne a szélein.
for i in range(cx-r,cx+r+1):
    for j in range(cy-r,cy+r+1):
        if sqrt((i-cx)**2+(j-cy)**2)<r:
            rajz.bits[j][i]=1
rajz.rajzol()

Ez a szócikk forráskódot tartalmaz, amely egy WikiMedia-kiegészítés segítségével olyan színesen jeleníthető meg, mint például ebben a Wikipédia-cikkben. A kiegészítést a Wikia-stáb ígérete szerint 2010 végéig frissítik, addig türelmet kérünk a fapados kinézet miatt.

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

A Wikia-hálózat

Véletlen wiki