I would like to write scripts (I am a script newbie) for
adding pictureframes to one layer, e.g. layer “pictureframes”
the size (width, height) of the pictureframes should be defined automatically by the width and height of our picture files (PNG)
the starting width, height, and filename should be stored with the pictureframe
Write a JSON file
collect all pictureframes from our layer and write the added values ( width, height, filename, real location(which we calculate from the 4 edgepoints, rotation, scale factor,…) to a JSON file
So my questions are:
Is Python right for this task and where to start?
How to open a pictureframe in Python and use the width and height of the picture file? (pixel of PNG should be mm of pictureframe)
What’s an easy way to add data (width, hight, name,…) to the pictureframe?
How to collect the added data, and write the JSON-file?
it seams I am on the right track. I have written this little Python script, to answer my first two questions:
import rhinoscriptsyntax as rs
import struct
import imghdr
def get_image_size(fname):
with open(fname, 'rb') as fhandle:
head = fhandle.read(24)
if len(head) != 24:
return
if imghdr.what(fname) == 'png':
check = struct.unpack('>i', head[4:8])[0]
if check != 0x0d0a1a0a:
return
width, height = struct.unpack('>ii', head[16:24])
elif imghdr.what(fname) == 'gif':
width, height = struct.unpack('<HH', head[6:10])
elif imghdr.what(fname) == 'jpeg':
try:
fhandle.seek(0) # Read 0xff next
size = 2
ftype = 0
while not 0xc0 <= ftype <= 0xcf:
fhandle.seek(size, 1)
byte = fhandle.read(1)
while ord(byte) == 0xff:
byte = fhandle.read(1)
ftype = ord(byte)
size = struct.unpack('>H', fhandle.read(2))[0] - 2
# We are at a SOFn block
fhandle.seek(1, 1) # Skip `precision' byte.
height, width = struct.unpack('>HH', fhandle.read(4))
except Exception: #IGNORE:W0703
return
else:
return
return width, height
def ToJSON():
filter = "PNG files (*.png)|*.png"
filename = rs.OpenFileName("Open PNG file", filter)
if not filename: return
width, height = get_image_size(filename)
rs.Command(''.join(['-_PictureFrame ',filename,' _AutoName=_Yes _AlphaTransparency=_Yes 0 ',str(width),',0']))
##########################################################################
# Check to see if this file is being executed as the "main" python
# script instead of being used as a module by some other python script
# This allows us to use the module which ever way we want.
if( __name__ == "__main__" ):
ToJSON()
I hope to find also answers for these two remaining questions. Happy if someone has an idea.
What’s an easy way to add data (width, hight, name,…) to the pictureframe?
How to collect the added data, and write the JSON-file?
Yes for point 1 you might take a look here, it looks related and has a simple example, but without getting the width and height from the png image. To get this, you might just use this:
import rhinoscriptsyntax as rs
from System.Drawing import Bitmap
def DoSomething():
filename = rs.OpenFileName("Open", "PNG Files (*.png)|*.png||")
if not filename: return
bitmap = Bitmap.FromFile(filename)
if not bitmap: return
print "Width: {}, Height: {}".format(bitmap.Width, bitmap.Height)
DoSomething()
You could use rs.SetUserText and rs.GetUserText methods which can be found in the python helpfile.
Just loop trough your picture frame objects once imported and detect them eg. with a name or custom usertext or by layer, collect the info in some lists and write the JSON file. Of course you can read things like width and height from the geometry (or png) directly, i guess even the path to the image can be read from the material texture. Here and here is some info about the json module.