-
-
Save jwlawson/778c33fd393317dc235ff89292283ccc to your computer and use it in GitHub Desktop.
Blender add-on which provides a function in the VSE to rescale images to their original aspect ratio.
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
| """ | |
| Blender add-on which provides a function in the VSE to rescale images to their | |
| original aspect ratio. | |
| Due to the inclusion of code licensed under GPLv2, this too is licensed under | |
| GPLv2. See: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html | |
| """ | |
| import bpy | |
| import os | |
| import struct, imghdr, re | |
| bl_info = { | |
| "name": "Rescale VSE Images", | |
| "description": "Adds transform layer to image to rescale to original aspect", | |
| "author": "J Lawson", | |
| "version": (1, 0), | |
| "blender": (2, 77, 0), | |
| "location": "?", | |
| "warning": "", # used for warning icon and text in addons panel | |
| "wiki_url": "", | |
| "tracker_url": "", | |
| "support": "COMMUNITY", | |
| "category": "Sequencer" | |
| } | |
| def get_image_size(fname): | |
| """ | |
| Return (width, height) for a given img file content. | |
| This function is heavily based on a similar funtion in `image.py` from the | |
| Draco dynamic web content system in python. Draco is available under the | |
| GPLv2. | |
| There are a number of similar functions floating around stack exchange, with | |
| slight changes to functionality. The version included here is based on | |
| Yantao Xie's version found here: | |
| https://stackoverflow.com/questions/15800704/ | |
| python-get-image-size-without-loading-image-into-memory | |
| """ | |
| with open(fname, 'rb') as fhandle: | |
| head = fhandle.read(32) | |
| if len(head) != 32: | |
| 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 | |
| elif imghdr.what(fname) == 'pgm': | |
| header, width, height, maxval = re.search( | |
| b"(^P5\s(?:\s*#.*[\r\n])*" | |
| b"(\d+)\s(?:\s*#.*[\r\n])*" | |
| b"(\d+)\s(?:\s*#.*[\r\n])*" | |
| b"(\d+)\s(?:\s*#.*[\r\n]\s)*)", head).groups() | |
| width = int(width) | |
| height = int(height) | |
| elif imghdr.what(fname) == 'bmp': | |
| _, width, height, depth = re.search( | |
| b"((\d+)\sx\s" | |
| b"(\d+)\sx\s" | |
| b"(\d+))", str).groups() | |
| width = int(width) | |
| height = int(height) | |
| else: | |
| return | |
| return width, height | |
| class Rescale_VSE_Image(bpy.types.Operator): | |
| bl_label = 'Rescale VSE Image' | |
| bl_idname = 'sequencerextra.rescaleimage' | |
| bl_description = 'Adds transform layer to image to rescale to original aspect' | |
| bl_options = {'REGISTER', 'UNDO'} | |
| @classmethod | |
| def poll(cls, context): | |
| """ Ensure that the function is only available for images """ | |
| scn = context.scene | |
| strip = scn.sequence_editor.active_strip | |
| if scn and scn.sequence_editor and strip: | |
| return strip.type in ('IMAGE') | |
| else: | |
| return False | |
| def execute(self, context): | |
| """ | |
| 1. Get the image path | |
| 2. Find the size of the image | |
| 3. Apply a transform to scale the image correctly | |
| """ | |
| scn = context.scene | |
| strip = scn.sequence_editor.active_strip | |
| file = os.path.realpath(bpy.data.filepath + "/.." + strip.directory + strip.name) | |
| size = get_image_size(file) | |
| render_setting = scn.render | |
| render_x = render_setting.resolution_x | |
| render_y = render_setting.resolution_y | |
| bpy.ops.sequencer.effect_strip_add(type='TRANSFORM') | |
| transform = scn.sequence_editor.active_strip | |
| transform.scale_start_x = render_y/render_x*size[0]/size[1] | |
| transform.scale_start_y = 1.0 | |
| return {'FINISHED'} | |
| def register(): | |
| bpy.utils.register_class(Rescale_VSE_Image) | |
| def unregister(): | |
| bpy.utils.unregister_class(Rescale_VSE_Image) |
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
| """ | |
| Blender add-on which provides a function in the VSE to rescale images to their | |
| original aspect ratio. | |
| """ | |
| import bpy | |
| import os | |
| from PIL import Image | |
| bl_info = { | |
| "name": "Rescale VSE Images", | |
| "description": "Adds transform layer to image to rescale to original aspect", | |
| "author": "J Lawson", | |
| "version": (1, 0), | |
| "blender": (2, 77, 0), | |
| "location": "?", | |
| "warning": "", # used for warning icon and text in addons panel | |
| "wiki_url": "", | |
| "tracker_url": "", | |
| "support": "COMMUNITY", | |
| "category": "Sequencer" | |
| } | |
| def get_image_size(fname): | |
| with Image.open(filename) as img: | |
| return img.size | |
| class Rescale_VSE_Image(bpy.types.Operator): | |
| bl_label = 'Rescale VSE Image' | |
| bl_idname = 'sequencerextra.rescaleimage' | |
| bl_description = 'Adds transform layer to image to rescale to original aspect' | |
| bl_options = {'REGISTER', 'UNDO'} | |
| @classmethod | |
| def poll(cls, context): | |
| """ Ensure that the function is only available for images """ | |
| scn = context.scene | |
| strip = scn.sequence_editor.active_strip | |
| if scn and scn.sequence_editor and strip: | |
| return strip.type in ('IMAGE') | |
| else: | |
| return False | |
| def execute(self, context): | |
| """ | |
| 1. Get the image path | |
| 2. Find the size of the image | |
| 3. Apply a transform to scale the image correctly | |
| """ | |
| scn = context.scene | |
| strip = scn.sequence_editor.active_strip | |
| file = os.path.realpath(bpy.data.filepath + "/.." + strip.directory + strip.name) | |
| size = get_image_size(file) | |
| render_setting = scn.render | |
| render_x = render_setting.resolution_x | |
| render_y = render_setting.resolution_y | |
| bpy.ops.sequencer.effect_strip_add(type='TRANSFORM') | |
| transform = scn.sequence_editor.active_strip | |
| transform.scale_start_x = render_y/render_x*size[0]/size[1] | |
| transform.scale_start_y = 1.0 | |
| return {'FINISHED'} | |
| def register(): | |
| bpy.utils.register_class(Rescale_VSE_Image) | |
| def unregister(): | |
| bpy.utils.unregister_class(Rescale_VSE_Image) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment