PIL Bit-tiefe ändern || C# Codes für python verwendbar machen
- __blackjack__
- User
- Beiträge: 14054
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Um .NET-DLLs aus CPython heraus zu nutzen gibt es übrigens ein Projekt: http://pythonnet.github.io/
Und natürlich IronPython, eine Python-Implementierung für die .NET-Laufzeitumgebung.
Und natürlich IronPython, eine Python-Implementierung für die .NET-Laufzeitumgebung.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Ah ok. Könntet ihr vielleicht mal kurz meine Klasse anschauen und sagen was ich besser machen könnte?
aber nur wenn ihr wollt:

Code: Alles auswählen
import os
from PIL import Image
import subprocess
import sys
class Convert:
counter = 0
def __init__(self, img_dir, save_dir=os.path.join(os.path.join(os.environ['USERPROFILE']), 'Pictures')):
"""Filetypes = png gif bmp tiff"""
self.img_dir = img_dir # Wert wird der Klasse zugeordnet
self.save_dir = save_dir # Wert wird der Klasse zugeordnet
filetypes = ["png", "tiff", "gif", "bmp"]
if os.path.isfile(img_dir): # Überpüft ob die Datei existiert, um einen Error abzufangen
pass
else:
raise FileNotFoundError("The file wasn't found: " + img_dir)
if os.path.isdir(save_dir): # Überpüft ob der Pfad existiert, um einen Error abzufangen
pass
else:
raise FileNotFoundError("The directory wasn't found: " + save_dir)
if img_dir.split(".")[-1] in filetypes:
pass
else:
raise Exception("File type must be one of the following: png, jpg, gif, tiff, ico, bmp")
def _check_dir(self, directory):
while directory.split("\\")[-1] in os.listdir(self.save_dir): # Wenn die Datei schon existiert, wird verhindert, dass sie überschrieben wird.
self.counter += 1
path = directory.split(".")
endung = path[-1] # Die Endung wird "extrahiert"
directory = path[0] # Der Pfad wird "extrahiert"
pfad = str(self.counter)+"."+endung # Der Pfad wird wieder zusammengesetzt
directory = os.path.join(directory +"_"+ pfad) # Der Pfad wird fertiggestellt
return directory # Der richtige Pfad wird zurückgeliefert
def to_jpg(self, qual=100):
"""Convert an image to jpg. Paramter: quality for the resulting jpg, standart set to 100"""
try:
image = Image.open(self.img_dir) # Bild wird geöffnet
except OSError:
raise OSError("This path is not valid: " + self.img_dir) # Wenn die datei nicht existiert, gibt es einen Errors
if image.mode != 'RGB':
image = image.convert('RGB') # Bild wird in den richtigen Modus konvertiert
_out = os.path.join(self.save_dir, "out.jpg") # Der Pfad wird zusammengetzt
out = self._check_dir(_out) # Der Pfad wird überprüft
image.save(out, "JPEG", quality=qual) # Das Bild wird gespeichert
# Das wiederholt sich auf alle methoden für das Konvertieren (to_...)
def to_png(self):
"""Convert an Image to png"""
try:
image = Image.open(self.img_dir)
except OSError:
raise OSError("This path is not valid: " + self.img_dir)
if image.mode != "RGBA":
image = image.convert("RGBA")
_out = os.path.join(self.save_dir, "out.png")
out = self._check_dir(_out)
image.save(out)
def to_tiff(self):
"""Convert an Image to tiff"""
try:
image = Image.open(self.img_dir)
except OSError:
raise OSError("This path is not valid: " + self.img_dir)
if image.mode != "CMYK":
image.convert("CMYK")
_out = os.path.join(self.save_dir, "out.tiff")
out = self._check_dir(_out)
image.save(out)
def to_gif(self):
"""Convert an Image to GIF"""
try:
image = Image.open(self.img_dir)
except OSError:
raise OSError("This path is not valid: " + self.img_dir)
if image.mode != "RGBA":
image.convert("RGBA")
_out = os.path.join(self.save_dir, "out.gif")
out = self._check_dir(_out)
image.save(out)
def to_ico(self, alpha_channel="y"):
"""Convert Image to ico. Parameter: Alpha_channel = 'y'/'n'"""
try:
image = Image.open(self.img_dir)
except OSError:
raise OSError("This path is not valid: " + self.img_dir)
if image.mode != "RGBA" and alpha_channel == "y":
image.convert("RGBA")
elif image.mode != "RGB" and alpha_channel != "y":
image.convert("RGB")
_out = os.path.join(self.save_dir, "out.ico")
out = self._check_dir(_out)
image.save(out)
def bit(self, bits):
"""Changes to bit depth. NOT AVAILABLE FOR JPG AND ICO"""
bits = str(bits)
pfad = self.img_dir.split(".")[-1]
_out = os.path.join(self.save_dir, "out."+str(pfad))
out = self._check_dir(_out)
args = [os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), "ConsoleApp1.exe"),
self.img_dir, bits, out]
subprocess.call(args)
def to_pdf(self):
"""Convert Image to pdf"""
try:
image = Image.open(self.img_dir)
except OSError:
raise OSError("This path is not valid: " + self.img_dir)
_out = os.path.join(self.save_dir, "out.pdf")
out = self._check_dir(_out)
image.save(out)
def to_tif(self):
"""Convert Image to TIF"""
try:
image = Image.open(self.img_dir)
except OSError:
raise OSError("This path is not valid: " + self.img_dir)
_out = os.path.join(self.save_dir, "out.TIF")
out = self._check_dir(_out)
image.save(out)
Klassenvariablen sind kein Ersatz für Instanzattribute.
os.path.join mit nur einem Argument aufzurufen ist unsinnig.
Wenn im if-Block nur `pass` steht, dann dreht man die Bedingung um.
In `_check_dir`: Pfade verarbeitet man nicht mit String-Operationen. Statt per os.listdir zu prüfen, würde man nur die Existenz des Pfads prüfen.
Willst Du wirklich den Pfad immer weiter mit _-Teilen erweitern?
In den ganzen to_-Methoden: Das Exceptionhandling ist totaler Quatsch, weil Du die eigentliche Fehlermeldung in eine weniger aussagekräftige umwandelst.
_check_dir wird gar nicht mit einem Verzeichnis aufgerufen, sondern mit einem Dateinamen.
Die ganzen to_Methoden sind fast identisch und könnten ohne Probleme in eine Methode zusammengefasst werden.
Insgesamt macht die Klasse wenig Sinn.
Du hast ein Inputfile und ein Outputfile. Das wäre deutlich lesbarer, wenn es eine convert-Funktion gäbe, die diese beiden Argumente bekommt.
Bleibt also:
os.path.join mit nur einem Argument aufzurufen ist unsinnig.
Wenn im if-Block nur `pass` steht, dann dreht man die Bedingung um.
In `_check_dir`: Pfade verarbeitet man nicht mit String-Operationen. Statt per os.listdir zu prüfen, würde man nur die Existenz des Pfads prüfen.
Willst Du wirklich den Pfad immer weiter mit _-Teilen erweitern?
In den ganzen to_-Methoden: Das Exceptionhandling ist totaler Quatsch, weil Du die eigentliche Fehlermeldung in eine weniger aussagekräftige umwandelst.
_check_dir wird gar nicht mit einem Verzeichnis aufgerufen, sondern mit einem Dateinamen.
Die ganzen to_Methoden sind fast identisch und könnten ohne Probleme in eine Methode zusammengefasst werden.
Insgesamt macht die Klasse wenig Sinn.
Du hast ein Inputfile und ein Outputfile. Das wäre deutlich lesbarer, wenn es eine convert-Funktion gäbe, die diese beiden Argumente bekommt.
Bleibt also:
Code: Alles auswählen
def make_unique_filename(filename):
counter = 0
original_filename, extension = os.path.splitext(filename)
while os.path.exists(filename):
counter += 1
filename = f"{original_filename}_{counter}{extension}"
return filename
def convert(inputfilename, outputfilename, qual=100, alpha_channel="y"):
outputfilename = make_unique_filename(outputfilename)
image = Image.open(inputfilename) # Bild wird geöffnet
_, extension = os.path.splitext(outputfilename)
if extension == '.jpg':
if image.mode != 'RGB':
image = image.convert('RGB') # Bild wird in den richtigen Modus konvertiert
type = "JPEG"
image.save(outputfilename, "JPEG", quality=qual) # Das Bild wird gespeichert
return
elif extension in ('.png', '.gif'):
if image.mode != "RGBA":
image = image.convert("RGBA")
elif extension == '.tiff':
if image.mode != "CMYK":
image.convert("CMYK")
elif extension == '.ico':
if image.mode != "RGBA" and alpha_channel == "y":
image.convert("RGBA")
elif image.mode != "RGB" and alpha_channel != "y":
image.convert("RGB")
image.save(outputfilename)
def bit(inputfilename, outputfilename, bits):
"""Changes to bit depth. NOT AVAILABLE FOR JPG AND ICO"""
outputfilename = make_unique_filename(outputfilename)
args = [os.path.join(os.path.dirname(os.path.abspath(__file__)), "ConsoleApp1.exe"),
inputfilename, str(bits), outputfilename]
subprocess.call(args)
Zuletzt geändert von Sirius3 am Donnerstag 11. Februar 2021, 14:17, insgesamt 1-mal geändert.