Resize Image on Upload

Does anyone know if there’s a way I can resize an image/blob before I upload it to my database?

Here’s what I’m doing right now to upload/


import fpmi
from java.net import URL
from javax.imageio import ImageIO		

#set the id
myID = event.source.parent.ComplaintId 	

if myID != None:
	#prompt user to select file		
	path = fpmi.file.openFile() 

	#if user selects a file, and does not click cancel, do this 
	if path != None:

		bytes = fpmi.file.readFileAsBytes(path) 
		#write the data to the database, and return the id of the new row 
		fpmi.db.runPrepStmt("INSERT INTO TBL_IMAGE (COMPLAINT_ID, IMAGEFILE)  VALUES(?,?)", (myID,bytes))  	

I guess another question could also be; ‘Is there a way to scale an image with the printable canvas’? That might be easier since that’s where this will eventually be displayed.

You should be able to set your scale in the paintable canvas, it’s just using the Java 2d drawing in there. I think you can call scale() to change it just like in the sample code, but I haven’t tried with an image.#### Scale graphics to actual component size dX = (event.width-1)/100.0 dY = (event.height-1)/100.0 g.scale(dX,dY)

Has anyone had success resizing images prior to upload to a DB?

I am having issues getting it resized before upload.

	from javax.imageio import ImageIO
	from java.io import ByteArrayInputStream
	
	# Grab the file name and data
	#filename = event.file.name
	filedata = event.file.getBytes()
	bais = ImageIO.read(ByteArrayInputStream(filedata))
	scaledImage = bais.getScaledInstance(320,-1,0)
	AAA = ImageIO.read((scaledImage))
	#filedata = AAA.asBytes()
	filedata = AAA

	# Use a query to insert the file	
	#databaseConnection = "AlternateDatabase"
	query = "INSERT INTO [Pipes].[FJC].[Images_JLH]  (JobCardID, Grind1) VALUES(9,CONVERT(varbinary(MAX), ?))"
	args = [filedata]
	system.db.runPrepUpdate(query, args)

You have the read and scale out of order:

	bais = ImageIO.read(ByteArrayInputStream(filedata))
	scaledImage = bais.getScaledInstance(320,-1,0)
	AAA = ImageIO.read((scaledImage))

should be

	bais = ImageIO.read(ByteArrayInputStream(filedata))
	image = ImageIO.read(bais)
	scaledImage = image.getScaledInstance(320,-1,0)

and then you need to use ImageIO.write() to get bytes you can store. (Via ByteArrayOutputStream, typically.)

PTurmel, Thanks for your help! I think I am closer but still getting an error.

TypeError: write(): 1st arg can't be coerced to java.awt.image.RenderedImage
    filedata = event.file.getBytes()
	bais = ImageIO.read(ByteArrayInputStream(filedata))
	scaledImage = bais.getScaledInstance(320,-1,0)
	
	OS = ByteArrayOutputStream()
	ImageIO.write(scaledImage, "jpg", OS)
	filedata = OS.toByteArray()

Hmm. BufferedImage is a subclass of Image that implements RenderedImage. .getScaledInstance() doesn’t. So it won’t be simple. You’ll have to use an AffineTransform with an AffineTransformOp. I use these in my streamer module but at at fixed scales, so I don’t have an example for you.

this worked for me
source

BufferedImage = java.awt.image.BufferedImage
filedata = event.file.getBytes()

bais = ImageIO.read(ByteArrayInputStream(filedata))
scaledImage = bais.getScaledInstance(320,-1,0)

bufferedThumbnail = BufferedImage(scaledImage.getWidth(None),scaledImage.getHeight(None),BufferedImage.TYPE_INT_RGB)
bufferedThumbnail.getGraphics().drawImage(scaledImage, 0, 0, None)

OS = ByteArrayOutputStream()
ImageIO.write(bufferedThumbnail, "jpg", OS)
filedata = OS.toByteArray()
1 Like

Are you using this within a perspective “onFileReceived” script? what librarys are you calling in? I get an error - global name 'java' is not defined on the first line of this code.


Yes, my full code is:

import base64
import java.awt
from javax.imageio import ImageIO
from java.io import ByteArrayInputStream
from java.io import ByteArrayOutputStream
import java.awt.image.BufferedImage as BufferedImage 
	
id = system.db.runScalarQuery('SELECT MAX(id) FROM Avaliacao5S',"DB_IGNITION") + 1
area = str(self.getSibling("Area").props.text)
filename = str(self.getSibling("data").props.text)
filedata = event.file.getBytes()
	
image = ImageIO.read(ByteArrayInputStream(filedata))

filedata = image.getScaledInstance(600, 600, java.awt.Image.SCALE_SMOOTH)
	
bufferedThumbnail = BufferedImage(filedata.getWidth(None),filedata.getHeight(None),BufferedImage.TYPE_INT_RGB)
bufferedThumbnail.getGraphics().drawImage(filedata, 0, 0, None)

OS = ByteArrayOutputStream()
ImageIO.write(bufferedThumbnail, "jpg", OS)
filedata = OS.toByteArray()
	
	
query = "INSERT INTO Avaliacao5SImages (id, filename, Area, filedata) VALUES(?, ?, ?, CONVERT(varbinary(MAX), ?))"
args = [id, filename, area, filedata]
system.db.runPrepUpdate(query, args)
1 Like

For displaying you can use a Paintable Canvas or download from database and display

Download Script:

x = system.db.runScalarQuery('select filedata from Avaliacao5SImages where id = 107',"DB_IGNITION")
from org.apache.commons.io import IOUtils
from java.io import ByteArrayInputStream,FileOutputStream

path = 'C:\Users\Desktop\img.png'
fileout = FileOutputStream(path)
pdf = ByteArrayInputStream(x)
IOUtils.copy(pdf, fileout);

fileout.close();

Edit: IOUtils can be replaced by system.file.writefile

Is there a way to use this by opening a file from a path first? Where it has:

filedata = event.file.getBytes()

I'm trying to replace it with something to open the image from a path (mainly for testing from the script console) but doesn't get a recognizable format.

Answered my own question, but in case anyone else want to know, just need to read the file in bytes in the beginning. I also included a bonus method to scale the size to a ratio instead of static (this keeps the picture in the same ratio).

imagePath = r"C:\Path\toImage"
bytes=system.file.readFileAsBytes(imagePath)
stream= ByteArrayInputStream(bytes)
image=ImageIO.read(stream)

#Scale to ratio
basewidth = 300
wpercent = (basewidth/float(image.width))
hsize = int((float(image.height)*float(wpercent)))
    
filedata = image.getScaledInstance(basewidth, hsize, java.awt.Image.SCALE_SMOOTH)
	
bufferedThumbnail = BufferedImage(filedata.getWidth(None), filedata.getHeight(None), BufferedImage.TYPE_INT_RGB)
bufferedThumbnail.getGraphics().drawImage(filedata, 0, 0, None)

OS = ByteArrayOutputStream()
ImageIO.write(bufferedThumbnail, "jpg", OS)
filedata = OS.toByteArray()
1 Like