1
$\begingroup$

Fairly new to python and blender, so apologies if this is super basic. I've searched around and haven't found an answer.

I'd like to render some procedurally generated objects with a background image. In case it makes a difference, I'm using:

enter image description here

I don't need any interaction between the generated object and the background image so I've left a skeleton script I'm using to render below

import os
DIR ="/home/path/to/folder"
bg_file = os.path.join(DIR, "myimage.jpg")
bg_img = bpy.data.images.load(bg_file)
bpy.data.scenes['Scene'].render.filepath = os.path.join(DIR, "image")
bpy.context.scene.camera = bpy.data.objects['Camera']
bpy.ops.render.render(write_still=True)

I managed to find some scripts that seem to be trying to do what I want online, but none that I could get to work. e.g.

import bpy
filepath = "/home/path/to/folder"
img = bpy.data.images.load(filepath)

for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        space_data = area.spaces.active
        bg = space_data.background_images.new()
        bg.image = img
        break

cam = bpy.data.cameras.new("Camera")
cam_ob = bpy.data.objects.new("Camera", cam)
bpy.context.scene.camera = cam_ob
bpy.context.scene.objects.link(cam_ob)
bpy.context.scene.objects.active = bpy.context.scene.objects["Camera"]

Any thoughts/tips would be greatly appreciated!

$\endgroup$
1
$\begingroup$

I tried the same thing above, but didn't work. What worked for me is with the textures. In this case, I think you also have to take care of the Texture fields.

  1. bpy.data.textures['Texture.001'].image=bg_img

It works if you need to Change just background

Also add this,

  1. bpy.context.scene.world.use_sky_paper = True
  2. Set also influence, horizontal

Sorry, I dont have enough credits to comment!

$\endgroup$
0
$\begingroup$

If it's for rendering an image, and the camera isn't moving around, put the pic on a plane.
File > User Prefs > Add-ons > Import-Export > Import Images as Planes

import bpy
bpy.ops.import_image.to_plane(files=[{"name":"starfield.jpg", "name":"starfield.jpg"}], directory="/home/eli/Pictures/Blend/Python/")
bpy.context.object.scale[0] = 9
bpy.context.object.scale[1] = 16
bpy.ops.transform.translate(value=(0, 0, -3))

That's my best advice, 'cuz I can't figure out the other way without seeing example code to begin with. I looked a a few, but they all looked like were for an earlier ver of Blender. I'll leave the notes of what was tried below, in case someone else can figure that method out.


I've got Blender rendering something else,
so I can't test it, but I believe this code is right:

import os
import bpy

DIR ='/home/eli/Pictures/Blend/Python/'
bg_file = os.path.join(DIR, 'starfield.jpg')
bg_img = bpy.data.images.load(bg_file)

for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        space_data = area.spaces.active
        bg = space_data.background_images.new()
        bg.image = bg_img
        break

bpy.data.scenes['Scene'].render.filepath = bg_file
bpy.context.scene.camera = bpy.data.objects['Camera']
bpy.ops.render.render(write_still=True)

... OK, I was under the assumption the second bit of code you posted was decent, and you essentially needed 'em merged. You're right, hmm...

This seems to be the way to load images:

import bpy img = bpy.ops.image.open(directory="/home/eli/Pictures/Blend/Python/", files=[{"name":"starfield.jpg", "name":"starfield.jpg"}])

I'm at a loss. If I add a Background node by hand, then check type, I get:

bpy.data.worlds['World'].node_tree.nodes['Background'].type
'BACKGROUND'

but if I try to use a script to add that type:

bpy.data.worlds['World'].node_tree.nodes.new('bpy.types.ShaderNodeBackground(img)')

nothing happens. You obviously have to define it before you can assign it,
though I'm guessing it's already pre-defined within shader data somewhere.

$\endgroup$
  • $\begingroup$ running this (with correct file location subbed in) in the new start up file just renders the default cube (with no background) for me? $\endgroup$ – Robert Hickman Mar 21 '17 at 12:23
0
$\begingroup$

One easy way to layer objects over an image without doing any python is to use blender's compositor.

You have to make sure that the 3D rendered scene is transparent ( technique explained by Not render sky texture? ) . Then rig up some nodes in the compositor (not texture or material nodes).

layer scene over background image using compositor

Once you have built these compositor nodes every frame you render will be mixed with the background image respecting the transparency of the 3D scene.

$\endgroup$
0
$\begingroup$

Here is a function that I wrote that seems to work for me:

def add_background(filepath):
    img = bpy.data.images.load(filepath)
    for area in bpy.context.screen.areas:
        if area.type == 'VIEW_3D':
            space_data = area.spaces.active
            bg = space_data.background_images.new()
            bg.image = img
            space_data.show_background_images = True
            break

    texture = bpy.data.textures.new("Texture.001", 'IMAGE')
    texture.image = img
    bpy.data.worlds['World'].active_texture = texture
    bpy.context.scene.world.texture_slots[0].use_map_horizon = True
$\endgroup$

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.