## load_bmp ##
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color, Ellipse, Line, Rectangle
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.factory import Factory
from kivy.properties import ObjectProperty
from kivy.uix.popup import Popup
import os
from os.path import join,isdir
import uuid
from datetime import datetime
from kivy.uix.filechooser import FileChooserIconView
from kivy.uix.filechooser import FileChooserListView
from kivy.clock import Clock
Window.clearcolor = (0,0,0,0)
class BtnChangeSelectFile(Button):
def on_release(self):
self.parent.DrawSelectFile()
class BtnSelectFile(Button):
def on_release(self):
self.parent.parent.lFile.text='\n'.join(self.parent.fc.selection)
self.parent.DrawBase()
class BtnChangeBase(Button):
def on_release(self):
self.parent.DrawBase()
class RGB():
def __init__(self,r,g,b):
self.r = r
self.g = g
self.b = b
class Output(BoxLayout):
def __init__(self,path,**kwargs):
super(Output,self).__init__(**kwargs)
outputtext = path
header = []
self.map_width = 0
self.map_height = 0
self.bitmap:RGB = []
self.list_la =[]
self.list_rc =[]
while True :
if not os.path.exists(path):
break
outputtext = "exists"
size = os.path.getsize(path)
if size < 54:
outputtext = "header not found"
break
with open(path,'rb') as f:
while True :
header = f.read(54)
if not ((header[0]==66)&(header[1]==77)):
outputtext = "this file is not bmp"
break
filesize = int(header[2]+(header[3]<<8)+(header[4]<<16)+(header[5]<<24))
headersize = int(header[10]+(header[11]<<8)+(header[12]<<16)+(header[13]<<24))
colorbit = int(header[28]+(header[29]<<8))
w = int(header[18]+(header[19]<<8)+(header[20]<<16)+(header[21]<<24))
h = int(header[22]+(header[23]<<8)+(header[24]<<16)+(header[25]<<24))
if headersize != 54:
outputtext = "this format not surpported"
break
if colorbit != 24:
outputtext = "24 bit color only"
break
### read bitmap ###
hsize = int((filesize - headersize)/h)
d = f.read(filesize - headersize)
for y in range(h):
for x in range(w):
idx = hsize * y + x * 3
self.bitmap.append(RGB(b = int(d[idx+0]),g = int(d[idx+1]),r = int(d[idx+2])))
outputtext ="colorbit:"+str(colorbit)+"width:"+str(w)+"/height:"+str(h)
self.map_width = w
self.map_height = h
break
break
print(outputtext)
self.text = outputtext
def Draw(self):
if not self.bitmap:
return
with self.canvas.before:
# clear all rectangle
for old in self.list_rc:
self.canvas.before.children.remove(old)
self.list_rc.clear()
# clear all label
for old in self.list_la:
self.canvas.before.children.remove(old.canvas)
self.list_la.clear()
w = self.size[0]/self.map_width
h = self.size[1]/self.map_height
idx = 0
for y in range(int(self.map_height)):
for x in range(int(self.map_width)):
Color(self.bitmap[idx].r/255,self.bitmap[idx].g/255,self.bitmap[idx].b/255)
idx = idx+1
self.list_rc.append(Rectangle(pos=(self.right-self.size[0]+x*w,self.top-self.size[1]+y*h),size=(w,h)))
class SubDisplay(BoxLayout):
def __init__(self,**kwargs):
super(SubDisplay,self).__init__(**kwargs)
self.fc=FileChooserListView()
#self.fc=FileChooserIconView()
self.fc.size_hint_y=7
self.fc.filters=['*.bmp']
self.mode = -1 # setup
Clock.schedule_interval(self.update, 1.0/3.0)
def update(self,dt):
if self.mode == 0: # Base Mode
self.main_disp.Draw()
return
def DrawBase(self):
self.clear_widgets()
self.orientation='vertical'
self.main_disp =Output(path=self.parent.lFile.text,size_hint_y=4)
b1 =BtnChangeSelectFile(text='SelectFile',size_hint_y=1)
self.add_widget(self.main_disp)
self.add_widget(b1)
self.mode = 0 # Base
def DrawSelectFile(self):
self.clear_widgets()
self.orientation='vertical'
b2=BtnSelectFile(text='SelectFile',size_hint_y=1)
b3=BtnChangeBase(text='QUIT',size_hint_y=1)
self.add_widget(self.fc)
self.add_widget(b2)
self.add_widget(b3)
self.mode = 1 # Select
class Display(BoxLayout):
orientation='vertical'
def __init__(self,**kwargs):
super(Display,self).__init__(**kwargs)
self.lFile = Label(text='No Selected',size_hint_y=1)
self.boxSub = SubDisplay(size_hint_y=8)
self.add_widget(self.lFile)
self.add_widget(self.boxSub)
self.boxSub.DrawBase()
class LoadBmpApp(App):
def build(self):
layout = Display()
return layout
if __name__=='__main__':
LoadBmpApp().run()
ビットマップは横一列のデータサイズが4バイト区切りで無いといけないというルールがあります。しかし、24ビット=3バイトで1ドットを表現している都合上、画像サイズによっては4で割り切れない場合があります。