Skip to content

Instantly share code, notes, and snippets.

@rodnaxel
Last active June 7, 2018 23:50
Show Gist options
  • Save rodnaxel/8d4473c0f8329a63f4dfb1f738704717 to your computer and use it in GitHub Desktop.
Save rodnaxel/8d4473c0f8329a63f4dfb1f738704717 to your computer and use it in GitHub Desktop.
image converter
#! /usr/bin/python3.6
# Name: imagehex
# Description: This programm to used convert image to hex sequence
# Author: Aleksandr Smirnov ([email protected])
import sys, os
from fileinput import filename
from PIL import Image
from PyQt5 import QtCore
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import inspect
def whoami(param=False):
func_info = "L{0}:{1}()".format(*inspect.stack()[1][2:4])
values = "param={}".format(inspect.getargvalues(inspect.stack()[1][0]).locals)
return (func_info + " " + values) if param else (func_info)
# I have 4 range of color [0:63], [64:127], [128:191], [192:255]
# format RGBAsp = 00_00_00_00 (8 bit color)
# | | | +- "b"
# | | +---- "g"
# | +------- "r"
# +---------- "a"
class ImageHex:
def __init__(self, filename, mode):
self.img = Image.open(filename).convert(mode)
self.height, self.width = self.img.size
def _convert_hex(self, rgba):
r, g, b, a = rgba
return format((a << 6) | (r << 4) | (g << 2) | b, '#04x')
def _get_gradient(self, value):
if (value <= 127):
return 0 if (value < 63) else 1
else:
return 3 if (value > 191) else 2
def _compress_pixel(self, pixel):
res = []
for channel in pixel:
res.append(self._get_gradient(channel))
return res
def compress(self):
res = []
for row in range(self.height):
line = []
for col in range(self.width):
pixel = self.img.getpixel((row, col))
line.append(self._convert_hex(self._compress_pixel(pixel)))
res.append(line)
return res
def get_size(self):
return self.img.size
def report(seq, filename='output.txt'):
with open(filename, 'w') as f:
for line in seq:
s = 'db' + ' ' + ",".join(line) + ';' + '\n'
f.write(s)
class ImageApp(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Image Converter")
self.setMaximumSize(380, 380)
self.paths = {'source': '', 'output': ''}
self.image = None
self.seq = []
self.createUI()
def createUI(self):
centralWgt = QWidget(self)
self.setCentralWidget(centralWgt)
# File dialog
pathbox = QGroupBox("Directories")
fl = QFormLayout(pathbox)
self.lines = dict(source=QLineEdit(), output=QLineEdit())
for k,v in self.lines.items():
v.setReadOnly(True)
v.setDisabled(True)
fl.addRow('{}:'.format(k.capitalize()), v)
# Tuner
tbox = QGroupBox("Tuner")
tbox.setCheckable(True)
tbox.setChecked(False)
tlayout = QHBoxLayout(tbox)
self.sliders = {}
for name in ('r', 'g', 'b', 'a'):
vbox = QVBoxLayout()
slider = QSlider(tbox)
slider.setFixedHeight(100)
slider.setRange(0,3)
slider.setTickPosition(QSlider.TicksBothSides)
self.sliders[name] = slider
vbox.addWidget(QLabel(name), QtCore.Qt.AlignTop)
vbox.addWidget(slider, QtCore.Qt.AlignLeft)
tlayout.addLayout(vbox)
# Buttons
btnWidget = QWidget(self)
btnLayout = QHBoxLayout(btnWidget)
self.buttons = {}
for (name, action) in (
("Open", self.onOpen ),
("Convert", self.onConvert),
("Report", self.onReport),
("About", self.onQuit),
("Quit", self.onQuit)
):
btn = QPushButton(name)
btn.clicked.connect(action)
btnLayout.addWidget(btn)
#if (name == "Convert") or (name == "Report"):
# btn.setDisabled(True)
self.buttons[name] = btn
# Status bar
sbar = QWidget()
#sbar.setFixedHeight(10)
self.image_size = QLabel("unknown")
size_layout = QFormLayout(sbar)
size_layout.addRow("size:", self.image_size)
self.statusBar().addWidget(sbar,2)
# Layouts
centralLayout = QVBoxLayout(centralWgt)
centralLayout.addWidget(pathbox)
centralLayout.addWidget(tbox)
centralLayout.addWidget(btnWidget, 2)
self._center()
print(self.height(), self.width())
def _center(self):
frameGm = self.frameGeometry()
screen = QApplication.desktop().screenNumber(QApplication.desktop().cursor().pos())
centerPoint = QApplication.desktop().screenGeometry(screen).center()
frameGm.moveCenter(centerPoint)
self.move(frameGm.topLeft())
def closeEvent(self, event):
self.onQuit()
def onOpen(self):
self.paths['source'] = QFileDialog.getOpenFileName(self, "Open Image", "",
"Image Files (*.png *.jpg *.bmp)")[0];
self.paths['output'] = os.path.join(os.path.dirname(self.paths['source']), 'output.txt')
for k,v in self.lines.items():
self.lines[k].setEnabled(True)
self.lines[k].setText(self.paths[k])
self.lines[k].setToolTip(self.paths[k])
self.image = ImageHex(self.paths['source'], mode="RGBA")
self.image_size.setText('{} x {}'.format(*self.image.get_size()))
self.buttons["Convert"].setEnabled(True)
def onConvert(self):
self.seq = self.image.compress()
report(self.seq, self.paths['output'])
self.buttons["Report"].setEnabled(True)
def onReport(self):
if os.path.exists(self.paths['output']):
self.open_report()
else:
self.statusBar().showMessage("Error! Don't exist file", 1000)
def open_report(self):
if sys.platform == 'win32':
cmd = "start"
else:
cmd = "xdg-open"
if (os.system(" ".join([cmd, self.paths['output']])) != 0):
self.statusBar().showMessage("Error. Can't open otput file")
def onQuit(self):
QtCore.QCoreApplication.exit(0)
if __name__ == "__main__":
app = QApplication(sys.argv)
image_app = ImageApp()
image_app.show()
sys.exit(app.exec_())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment