Created
June 27, 2019 03:06
-
-
Save MCJack123/fc38b3ef79ba3ae533defe4fcb7c509b to your computer and use it in GitHub Desktop.
PNG manipulation module in Python 2/3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import png # pip install pypng | |
class pixel: | |
def __init__(self, x=0, y=0, r=0, g=0, b=0, a=0): | |
self.x = x | |
self.y = y | |
self.r = r | |
self.g = g | |
self.b = b | |
self.a = a | |
def clone(self, r=None, g=None, b=None, a=None): | |
return pixel(self.x, self.y, self.r if r is None else r, self.g if g is None else g, self.b if b is None else b, self.a if a is None else a) | |
class image_scripter: | |
progress = 0.0 | |
# Create a scripter from a file name or file object | |
def __init__(self, file): | |
self._image_in = png.Reader(file) | |
self.width, self.height, data, self.metadata = self._image_in.read() | |
self._image_in_data = [] | |
self._image_out_data = None | |
y = 0 | |
for row in data: | |
self._image_in_data.insert(y, [] * (self.width * self.metadata["planes"])) | |
for x in range(0, self.width * self.metadata["planes"], self.metadata["planes"]): | |
self._image_in_data[y].insert(int(x/self.metadata["planes"]), pixel(int(x/self.metadata["planes"]), y, row[x], row[x+1] if self.metadata["planes"] > 1 else 0, row[x+2] if self.metadata["planes"] > 2 else 0, row[x+3] if self.metadata["planes"] > 3 else 0)) | |
y+=1 | |
# Returns a pixel at a location | |
def get(self, x, y): | |
return self._image_in_data[y][x] | |
# Sets a pixel | |
def set(self, px): | |
self._image_in_data[px.y][px.x] = px | |
# Operates on the image using a function | |
# Any previous output will cycle to input | |
# Prototype: func(scripter, pixel) | |
def operate(self, func): | |
if self._image_out_data != None: | |
self._image_in_data = self._image_out_data | |
self._image_out_data = [] | |
for i in range(0, self.height): self._image_out_data.insert(i, [] * (self.width * self.metadata["planes"])) | |
i = 0 | |
for row in self._image_in_data: | |
for px in row: | |
self.progress = i / (self.width * self.height) | |
self._image_out_data[px.y].insert(px.x, func(self, px)) | |
i+=1 | |
self.progress = 1.0 | |
# Writes the output to a file | |
def write(self, file): | |
img = png.Writer(self.width, self.height, size=self.metadata["size"], greyscale=self.metadata["greyscale"], alpha=self.metadata["alpha"], planes=self.metadata["planes"], bitdepth=self.metadata["bitdepth"], interlace=self.metadata["interlace"], gamma=self.metadata["gamma"]) | |
rows = [] | |
for i in range(0, self.height): rows.insert(i, [0] * (self.width * self.metadata["planes"])) | |
y=0 | |
for r in self._image_out_data: | |
x=0 | |
for px in r: | |
rows[y][x*self.metadata["planes"]] = px.r | |
if self.metadata["planes"] > 1: rows[y][x*self.metadata["planes"]+1] = px.g | |
if self.metadata["planes"] > 2: rows[y][x*self.metadata["planes"]+2] = px.b | |
if self.metadata["planes"] > 3: rows[y][x*self.metadata["planes"]+3] = px.a | |
x+=1 | |
y+=1 | |
fp = open(file, "wb") | |
img.write(fp, rows) | |
fp.close() | |
# Opens an image, operates on it, and writes the output to a file | |
def run(input, func, output): | |
scripter = image_scripter(input) | |
scripter.operate(func) | |
scripter.write(output) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Turns image grayscale and flips it upside down | |
import imagescripter | |
def test(scripter, pixel): | |
p = scripter.get(pixel.x, scripter.height - pixel.y - 1) | |
avg = int((p.r + p.g + p.b) / 3) | |
return p.clone(avg, avg, avg) | |
imagescripter.run("input.png", test, "output.png") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment