In the previous article Script about Blender camera operation A script that makes the specified range of the image displayed in the image editor a sketch of the camera I organized it a little and made it an add-on. Annotation to bound panel is added to the image tab. Can you see that the area where the annotation line is drawn is the sketch of the camera? The rendering resolution is also specified in the specified range of resolutions.
This is a very niche feature in itself If you apply it, you may be able to use it in an interesting way.
CropBG_Annotate.py
bl_info = {
"name" : "Crop image from Annotation",
"author" : "Yukimituki",
"description" : "",
"blender" : (2, 80, 0),
"version" : (0, 0, 1),
"location" : "",
"warning" : "",
"category" : "Generic"
}
import bpy
import os
from bpy.types import (
PropertyGroup,
)
class IMAGE_PT_Annotatebound(bpy.types.Panel):
bl_idname = "annotation_to_bound.panel"
bl_label = "Annotation to bound"
bl_space_type = "IMAGE_EDITOR"
bl_region_type = "UI"
bl_category = "Image"
#Definition of drawing
def draw(self, context):
layout = self.layout
row = layout.row()
row.operator("action.crop_stroke_bound")
class IMAGE_OT_Stroke(bpy.types.Operator):
'''Crop the range specified by the annotation'''
bl_idname = "action.crop_stroke_bound"
bl_label = "get_stroke"
def execute(self, context):
scene = context.scene
#Get annotation line
strokes = context.annotation_data.layers.active.active_frame.strokes
#Annotations are filtered because some are used for 3D views and some are used for 3D views.
strokes_2d = [ s for s in strokes if s.display_mode == '2DSPACE']
bbox_2d = self.get_stroke_bound( strokes_2d )
#Get information on the displayed image
img = context.space_data.image
#Set the sketch image of the camera
crop_size = self.set_cameraBG(context, img, bbox_2d)
#Rendering image size settings
scene.render.resolution_x = crop_size[0]
scene.render.resolution_y = crop_size[1]
return {'FINISHED'}
def get_stroke_bound(self, strokes):
'''Get a range of annotations'''
x_list = []
y_list = []
for stroke in strokes:
x_list += [pos.co[0] for pos in stroke.points]
y_list += [pos.co[1] for pos in stroke.points]
bbox = [min(x_list),min(y_list), max(x_list), max(y_list)]
return(bbox)
def set_cameraBG(self, context, image_object, bbox):
'''Set camera background'''
#Get camera information
camera = context.scene.camera
camera.data.show_background_images = True
#Sketch image settings
bg_image = camera.data.background_images.new()
bg_image.image = image_object
bg_size = image_object.size
#Setting the display range of the sketch
bg_image.frame_method = 'CROP'
crop_size = [(bbox[2] -bbox[0])*bg_size[0], (bbox[3] -bbox[1])*bg_size[1]]
#Cut out the background trim by putting it in the frame based on the larger one compared to the ratio of the background image.
if bg_size[0] * crop_size[0] > bg_size[1] * crop_size[1]:
bg_scale = bg_size[0] / crop_size[0]
else:
bg_scale = bg_size[1] / crop_size[1]
bg_image.scale = bg_scale
#Set the center position of the sketch
bg_image.offset = ((bbox[0] + bbox[2] -1) *-0.5 *bg_scale, (bbox[1]+ bbox[3] -1) *-0.5 *bg_scale)
return( crop_size )
classes = (
IMAGE_PT_Annotatebound,
IMAGE_OT_Stroke,
)
#####################################
def register():
for cls in classes:
bpy.utils.register_class(cls)
#bpy.app.translations.register(__name__, translation_dict) #Dictionary registration
def unregister():
#bpy.app.translations.unregister(__name__) #Delete dictionary
for cls in reversed(classes):
bpy.utils.unregister_class(cls)
if __name__ == "__main__":
register()
#######################################
Recommended Posts