Script to save MoI screen shot w/ transparent BG to clipboard

Next
 From:  ed (EDDYF)
10393.1 
Michael -

I'm using your keyboard script below to save a screenshot of my models, on a plain white background, as PNG.

Can it be modified to:

1) Save it on a transparent background?

2) Save it to the clipboard rather than to a file?


I'm working on a technique to replicate a particular illustration style using Affinity Photo.

I can get the shaded model on a transparent background by saving as a PDF, but saving to clipboard would eliminate a couple of steps as AP can create a new file or layer directly from the clipboard.


Ed Ferguson

script: var prev_background = moi.view.viewportBackgroundColor; moi.view.viewportBackgroundColor = 0xFFFFFF; moi.view.lineWidth = 4; moi.grid.display = false; moi.grid.showXYAxes = false; moi.view.showAxisIcon = false; moi.view.showViewTitles = false; var img = null; try { img = moi.ui.getActiveViewport().render( 4000, 2500 ); } catch(e){} moi.view.lineWidth = 1; moi.grid.display = true; moi.grid.showXYAxes = true; moi.view.showAxisIcon = true; moi.view.showViewTitles = true; moi.view.viewportBackgroundColor = prev_background; var name = img.getSaveFileName(); if ( name != '' ) img.save( name );
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
10393.2 In reply to 10393.1 
Hi Ed,

re:
> 1) Save it on a transparent background?

Sorry no the viewport renderer that uses the GPU doesn't work with a transparent background, the way it currently works it is expecting to blend against a non-transparent background.

There is another renderer that is CPU based and used to generate the shaded background image for .ai and .pdf format exports though. For .ai export there will be a .png companion file for the shaded background and it will have a transparent background so you could try harvesting it out of an .ai format export.


> 2) Save it to the clipboard rather than to a file?

This one you can do by using view.renderToClipboard() instead of view.render(), something like this (warning, untested):

script: var prev_background = moi.view.viewportBackgroundColor; moi.view.viewportBackgroundColor = 0xFFFFFF; moi.view.lineWidth = 4; moi.grid.display = false; moi.grid.showXYAxes = false; moi.view.showAxisIcon = false; moi.view.showViewTitles = false; try { moi.ui.getActiveViewport().renderToClipboard( 4000, 2500 ); } catch(e){} moi.view.lineWidth = 1; moi.grid.display = true; moi.grid.showXYAxes = true; moi.view.showAxisIcon = true; moi.view.showViewTitles = true; moi.view.viewportBackgroundColor = prev_background;

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  ed (EDDYF)
10393.3 In reply to 10393.2 
Thanks Michael -

I just found your keyboard script from 2017:

script: /* Copy PDF format to clipboard */ moi.geometryDatabase.copyToClipboardPDF();

Also Metin Seven's post from 2017 stating that he uses it with Affinity Designer.

I tried it with both Affinity Photo and Affinity Designer and it solves both of my wishes above.

When I paste into Affinity Photo I just have to go to Document > Transparent Background and I have what I need.

Ed Ferguson
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
10393.4 In reply to 10393.3 
Hi Ed, I'm glad you figured it out! Sorry I seem to have skipped over part of your message that you were already currently using PDF to a file.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Frenchy Pilou (PILOU)
10393.5 
Affinity Photo Affinity & Designer is a very good low cost alternative to Toshop & Illustrator!
(free update infinite)
---
Pilou
Is beautiful that please without concept!
My Moi French Site My Gallery My MagicaVoxel Gallery
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  pior (PIOR_O)
10393.6 
Hello Michael, everyone,

Is there any way to use this rendering method to generate a viewport render constrained to the precise boundaries of an object, at specific pixel dimensions ?

Practically speaking I am working with pages that have set dimensions ( 4096pix*2048pix, portrait), doing line work within these boundaries. I'd like to be able to render out these layouts at exactly their original dimensions. Like so :



The scene object dimensions (transparent reference, page outline, drawing) do not matter in my case - for instance the blue rectangle representing the outline of the page was drawn as 20cmx10cm, but it could have been anything else of the same proportions. What I am after is to be able to render out the contents of said rectangle at arbitrary pixel dimensions (cropping right over the center of these blue lines as opposed to outside of them, as to not introduce any scaling). This would essentially save me two tedious import and render steps using Inkscape or Affinity :)

I should also probably mention that I am already getting very close to my intended result by manually framing the viewport as close as possible to the edge of the intended page outlines and using the render to clipboard command shown earlier in this thread. It's not perfect, but maybe there is an alternate way of framing the viewport to the bounding box of an object without any borders ?

I understand that this is way outside the intended scope of the program of course. I hope this makes sense !

EDITED: 12 Aug 2021 by PIOR_O


  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
10393.7 In reply to 10393.6 
Hi pior, I'm not entirely sure that I'm following all of what you described but for specific pixel sizes the script in the first message of this same thread can do that.

This is the part of the script that has the pixel dimensions:

.render( 4000, 2500 );

That's making an image of 4000 pixels in width and 2500 in height. Replace the 4000 and 2500 with your desired pixel sizes instead.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  pior (PIOR_O)
10393.8 In reply to 10393.7 
Hello Michael ! Thank you for chiming in so quickly as always.
I absolutely should have been more clear and should have annotated the diagram to begin with. Here goes :



On this diagram I would describe the blue rectangle/boundary as my desired "page". Within this page lies a subject (here a simple character pinup outline, drawn in black), which does not fully fill up the page. That is to say, the bounding box of the content is much narrower than my desired render.

At a high level the thing I am after is a way to render out this rectangular blue "page", at given pixel width and height or as some multiple of its current screen presence (which I could then scale down later, respecting the proportions). 2D vector drawing programs tend to have a few options for that (rendering out the page itself, cropping things down to the bounding box of the art content, and so on).

Of course, having such a rectangle to define the page boundary is just one way I can think of to define this desired rendering area. If I could somehow feed up the coordinates of the 4 corner points (0 0, 0 10, 20 0, 20,10) and instruct the renderer to render the content within these corners at a set pixel width/height, that would work too.

The one tricky aspect of it all is that if the page boundaries were to be defined by a rectangle shape in the scene, this shape will have line thickness once rendered, hence the resulting image wouldn't quite match the original layout anymore if the boundaries were defined by the rendered objects with thick lines.

I hope this makes more sense !

EDITED: 12 Aug 2021 by PIOR_O


  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
10393.9 In reply to 10393.8 
Hi pior,

re:
> If I could somehow feed up the coordinates of the 4 corner points (0 0, 0 10, 20 0, 20,10) and instruct
> the renderer to render the content within these corners at a set pixel width/height, that would
> work too.

Well the renderer just renders the view, there isn't any way to tell it to render something different. So you would need to manipulate the view to do what you need.

For a first step if you trigger a Reset on the view, that will center it on the bounding rectangle of the selected objects but leave a little bit of border space around it. Then for an ortho view the size of the viewplane can be set to the size of the geometry to frame it without any border space.

That would go something like this:

script: var objs = moi.geometryDatabase.getSelectedObjects(); var vp = moi.ui.getActiveViewport(); if ( vp.projection == 'Parallel' && objs.length > 0 ) { vp.reset( 'selected' ); var bbox = objs.getHighAccuracyBoundingBox(); vp.fieldOfViewAngle = bbox.yLength; }

I think the on screen display may not show the top and bottom of the objects because they will be running right over the border decorations of the viewport but on a scripted render call the border decorations won't be shown.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
 From:  pior (PIOR_O)
10393.10 In reply to 10393.9 
Well, this is *exactly* it ! All I had to do was to feed it square values (in this present case, 4096*4096), otherwise I somehow end up with a smaller rendered "page" inside the full render - and then all I have to do is to crop the result down to 4096*2048 in PS. This basically saves me about 10 minutes of exporting/importing back and forth to other vector applications just to get my precise lineart render out of MOI. And with the ability to render to clipboard I don't even have to worry with intermediate files anymore either. And of course everything lines up perfectly with the original layout, this is brilliant. Thank you so much !

FWIW the full code turns out to be :

script: var objs = moi.geometryDatabase.getSelectedObjects(); var vp = moi.ui.getActiveViewport(); if ( vp.projection == 'Parallel' && objs.length > 0 ) { vp.reset( 'selected' ); var bbox = objs.getHighAccuracyBoundingBox(); vp.fieldOfViewAngle = bbox.yLength; }; var prev_background = moi.view.viewportBackgroundColor; moi.view.viewportBackgroundColor = 0xFFFFFF; moi.view.lineWidth = 2; moi.grid.display = false; moi.grid.showXYAxes = false; moi.view.showAxisIcon = false; moi.view.showViewTitles = false; var img = null; try { img = moi.ui.getActiveViewport().renderToClipboard( 4096, 4096 ); } catch(e){} moi.view.lineWidth = 1; moi.grid.display = true; moi.grid.showXYAxes = true; moi.view.showAxisIcon = true; moi.view.showViewTitles = true; moi.view.viewportBackgroundColor = prev_background;

EDITED: 12 Aug 2021 by PIOR_O

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged
 

Reply to All Reply to All