I'm trying to allow my text edit to copy and paste an image from QTextEdit to Microsoft Paint.
Currently I have a custom text edit that allows me to paste images into the text edit. I save the entire document as HTML and reload it later so when I paste the images I use <img src= \"data:image/*;base64," + binary + "\" max-width=100% max-height=100%/> where the binary is a resized base64 binary image. This way the image binary is embedded into the HTML and I don't need to keep track of any source images.
Here is the code for my QTextEdit that allows for that paste.
class TextEdit(QTextEdit):
def __init__(self):
super().__init__()
self.setMaximumWidth(800)
self.setStyleSheet("background-color: rgb(255, 255, 255);")
def canInsertFromMimeData(self, source):
if source.hasImage():
return True
else:
return super(TextEdit, self).canInsertFromMimeData(source)
def insertFromMimeData(self, source):
cursor = self.textCursor()
document = self.document()
if source.hasUrls():
for u in source.urls():
file_ext = os.path.splitext(str(u.toLocalFile()))[1].lower()
if u.isLocalFile() and file_ext in IMAGE_EXTENSIONS:
img = Image.open(u.toLocalFile())
width, height = img.size
max_width = int(document.pageSize().width())
max_height = int(max_width * height / width)
if width > max_width or height > max_height:
img = img.resize((max_width, max_height), Image.ANTIALIAS)
output = io.BytesIO()
img.save(output, format=file_ext.replace(".",""), quality=3000)
binary = str(base64.b64encode(output.getvalue()))
binary = binary.replace("b'", "")
binary = binary.replace("'", "")
HTMLBin = "<img src= \"data:image/*;base64," + binary + "\" max-width=100% max-height=100%/>"
cursor.insertHtml(HTMLBin)
return
else:
# If we hit a non-image or non-local URL break the loop and fall out
# to the super call & let Qt handle it
break
else:
# If all were valid images, finish here.
return
elif source.hasImage():
img = source.imageData()
#Save the image from the clipboard into a buffer
ba = QtCore.QByteArray()
buffer = QtCore.QBuffer(ba)
buffer.open(QtCore.QIODevice.WriteOnly)
img.save(buffer, 'PNG')
#Load the image binary into PIL.Image (Python Image Library)
img = Image.open(io.BytesIO(ba.data()))
#Find what the max size of the document is.
width, height = img.size
max_width = 775
max_height = int(max_width * height / width)
#Resize to make sure the image fits in the document.
if (width > max_width or height > max_height) and (max_width!=0 and max_height!=0):
img = img.resize((max_width, max_height), Image.ANTIALIAS)
#Convert binary into a string representation of the base64 to embed the image into the HTML
output = io.BytesIO()
img.save(output, format='PNG', quality=95)
binary = str(base64.b64encode(output.getvalue()))
# base64_data = ba.toBase64().data()
# binary = str(base64_data)
binary = binary.replace("b'", "")
binary = binary.replace("'", "")
#Write the HTML and insert it at the Document Cursor.
HTMLBin = "<img src= \"data:image/*;base64," + binary + "\" max-width=100% max-height=100%> </img>"
cursor.insertHtml(HTMLBin)
return
elif source.hasHtml():
html = source.html()
cursor.insertHtml(html)
return
super(TextEdit, self).insertFromMimeData(source)
Now what I need to do is when the image is copied again, I basically need to remove the HTML img tag around the binary and copy just the binary.
I tried to overload the QTextEdit.copy() method which didn't seem to do anything, and I tried to overwrite QTextEdit.createMimeDataFromSelection() but I wasn't able to find a way to get the copy to work the same as before once I did that.
Does anyone have any information on how to accomplish this? I'd like the solution to be within my custom QTextEdit and not be done outside of that class just so I can re-use this same functionality elsewhere with other projects.