2
$\begingroup$

I have a lot of camera background images for reference in an architectural project. I made an animation where, for each frame:

  • The camera position is defined, corresponding to one of the images
  • the same image is used as viewport background. Images have been grouped in a video, and the video is used as a camera background instead.

This way I can change my reference image and match the point of view by just changing the current frame.

However some of the images are in portrait mode, some in landscape mode, and the render size ("resolution") has to be switched accordingly, frame by frame.

enter image description here

This works manually, but I'd like to do this automatically.

Example: Selecting frame 30 to set the (animated) camera viewpoint to some actual picture which was shot in portrait mode and inserted in frame 30 of the background video:

enter image description here

The 30rd background video frame is stretched because the "resolution" is not set accordingly. Is there a bypass?

$\endgroup$
  • $\begingroup$ Sorry to say but there is no bypass to this. $\endgroup$ – IgamerAmrit Sep 10 '18 at 9:33
  • $\begingroup$ this could be done in Python. Are you expecting to click Animation and for Blender render out each frame with its unique settings? Or are you talking about changing the frame in Blender to aid your work flow? $\endgroup$ – rob Sep 10 '18 at 9:36
  • $\begingroup$ @rob: Frames are used here as a bypass for Blender not having a list of camera viewpoints that can be selected, it's an aid. There is no actual animation purpose. Python is a good solution for me. $\endgroup$ – mins Sep 11 '18 at 6:46
2
$\begingroup$

I think the only way to do that is to use a python script to adjust and render each frame.

import bpy

res_landscape = [1920,1080]
res_portrait = [1080,1920]

frame_res = {
    1: res_landscape,
    2: res_landscape,
    3: res_portrait,
    4: res_portrait,
    5: res_landscape,
    }

scn = bpy.context.scene

for f,r in frame_res.items():
    scn.frame_set(f)
    scn.render.resolution_x = r[0]
    scn.render.resolution_y = r[1]
    scn.render.filepath = '//renders/image{:03}.jpg'.format(f)
    bpy.ops.render.render('INVOKE_DEFAULT', write_still=True)
$\endgroup$
  • $\begingroup$ That's the idea, +1. Currently this leads to Blender freezing when the script is executed (I'll try to fix this). That set apart, I don't want to render all frames in order and stop. Instead, the script must permanently listen to the current animation frame, selected manually, and change the resolution accordingly. $\endgroup$ – mins Sep 11 '18 at 7:48
  • $\begingroup$ @mins Blocking is known, there is this solution. What I was trying to remember yesterday was using 'INVOKE_DEFAULT'. The only way to automate it would be using bpy.app.handlers but they don't appear to let you change the resolution. The other option is to replace the render button and shortcut to run your operator that does these steps. $\endgroup$ – sambler Sep 11 '18 at 8:23
  • $\begingroup$ @mins didn't work for me, tried most possibilities. $\endgroup$ – sambler Sep 11 '18 at 9:31
  • $\begingroup$ I derived a solution from your suggestion, and posted it as an answer (obviously wouldn't fit in a comment. All credit to you indeed). $\endgroup$ – mins Sep 11 '18 at 9:41
1
$\begingroup$

This is my solution, greatly inspired from @sambler elements (please give him credits, not me).

import bpy

# Define size elements
mx, mn = 1500,1000

# There are less portrait frames, let see them as exceptions
portrait_frames = 11,12,13,14,16,19,24,27,30,31, \
                  33,34,35,36,38,39,40,42,43,44,45

# Define a callback function to call when scene current frame changes
def chg_res(scene):
    # Get frame number
    f = scene.frame_current

    # Set desired resolution for this frame
    if f in portrait_frames:
        scene.render.resolution_x = mn
        scene.render.resolution_y = mx
    else:
        scene.render.resolution_x = mx
        scene.render.resolution_y = mn

# Register callback in Blender event system (once)
bpy.app.handlers.frame_change_pre.append(chg_res)

and the result:

enter image description here

(The frame is manually changed. This leads to the camera resolution being changed by the callback function. The background image and the camera position/orientation are changed by normal animation keyframing).

$\endgroup$
  • $\begingroup$ Is playback in the viewport OK for you? I tried it using render animation and the handlers don't change res on frame change during rendering. If manually changing frame works for you thats great. $\endgroup$ – sambler Sep 11 '18 at 10:00
  • $\begingroup$ @sambler: Yes this is what I was looking for, it's just a bypass to quickly change the camera point of view (to model objects from a series of photos). IMHO, this feature is missing in Blender. $\endgroup$ – mins Sep 11 '18 at 10:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.