swf export and pdf multipage

1.5.0

- added: swf export (include binary for linux and windows)
- added: pdf single multipage file exports
main
pullusb 2023-06-29 18:15:59 +02:00
parent c8e576b7e7
commit 4721380344
6 changed files with 167 additions and 6 deletions

View File

@ -14,6 +14,12 @@ Activate / deactivate layer opacity according to prefix
Activate / deactivate all masks using MA layers Activate / deactivate all masks using MA layers
--> -->
1.5.0
- added: swf export (include binary for linux and windows)
- added: pdf single multipage file exports
1.4.1 1.4.1
- added: expose button for output file de-numbering - added: expose button for output file de-numbering

View File

@ -1,4 +1,6 @@
import bpy import bpy
import sys
import subprocess
from . import fn from . import fn
from pathlib import Path from pathlib import Path
from itertools import groupby from itertools import groupby
@ -71,9 +73,36 @@ def export_all_selected_frame_as_svg():
print('Done') print('Done')
def pdf_render(fp): def pdf_render(fp, multi_page=False):
'''Render a sequence of pdf and return path to folder
or render a multipage pdf (in place of parent folder) and return path to file
'''
scn = bpy.context.scene scn = bpy.context.scene
if multi_page:
## Set folder name (when using sequence) as output with pdf extension
fp = fp.parent
fp.parent.mkdir(parents=True, exist_ok=True) # mode=0o777 fp.parent.mkdir(parents=True, exist_ok=True) # mode=0o777
if multi_page:
## In case of sequence path:
## Remove padding separator (or add scene range: "0100-0230" ?)
# fp = fp.with_stem(fp.stem.rstrip('-_. ')) # strip typical padding separator
fp = fp.with_suffix('.pdf')
# print('Exporting multi-page pdf at: ', fp)
bpy.ops.wm.gpencil_export_pdf(filepath=str(fp),
check_existing=False, # True by default
use_fill=True,
selected_object_type='ACTIVE', # VISIBLE, SELECTED
stroke_sample=0,
use_normalized_thickness=False,
frame_mode='SCENE')
return fp
## Sequence
for fnum in range(scn.frame_start, scn.frame_end + 1): for fnum in range(scn.frame_start, scn.frame_end + 1):
# print('fnum: ', fnum) # print('fnum: ', fnum)
scn.frame_current = fnum scn.frame_current = fnum
@ -92,6 +121,107 @@ def pdf_render(fp):
stroke_sample=0, stroke_sample=0,
use_normalized_thickness=False, use_normalized_thickness=False,
frame_mode='ACTIVE') frame_mode='ACTIVE')
return fp.parent
def swf_render(fp):
'''
Render as pdf then convert to swf using pdf2swf
-h , --help Print short help message and exit
-V , --version Print version info and exit
-o , --output file.swf Direct output to file.swf. If file.swf contains '%' (file%.swf), then each page goes to a separate file.
-p , --pages range Convert only pages in range with range e.g. 1-20 or 1,4,6,9-11 or
-P , --password password Use password for deciphering the pdf.
-v , --verbose Be verbose. Use more than one -v for greater effect.
-z , --zlib Use Flash 6 (MX) zlib compression.
-i , --ignore Allows pdf2swf to change the draw order of the pdf. This may make the generated
-j , --jpegquality quality Set quality of embedded jpeg pictures to quality. 0 is worst (small), 100 is best (big). (default:85)
-s , --set param=value Set a SWF encoder specific parameter. See pdf2swf -s help for more information.
-w , --samewindow When converting pdf hyperlinks, don't make the links open a new window.
-t , --stop Insert a stop() command in each page.
-T , --flashversion num Set Flash Version in the SWF header to num.
-F , --fontdir directory Add directory to the font search path.
-b , --defaultviewer Link a standard viewer to the swf file.
-l , --defaultloader Link a standard preloader to the swf file which will be displayed while the main swf is loading.
-B , --viewer filename Link viewer filename to the swf file.
-L , --preloader filename Link preloader filename to the swf file.
-q , --quiet Suppress normal messages. Use -qq to suppress warnings, also.
-S , --shapes Don't use SWF Fonts, but store everything as shape.
-f , --fonts Store full fonts in SWF. (Don't reduce to used characters).
-G , --flatten Remove as many clip layers from file as possible.
-I , --info Don't do actual conversion, just display a list of all pages in the PDF.
-Q , --maxtime n Abort conversion after n seconds. Only available on Unix.
##with -s arg:
PDF Parameters:
PDF device global parameters:
fontdir=<dir> a directory with additional fonts
font=<filename> an additional font filename
pages=<range> the range of pages to convert (example: pages=1-100,210-)
zoom=<dpi> the resultion (default: 72)
languagedir=<dir> Add an xpdf language directory
multiply=<times> Render everything at <times> the resolution
poly2bitmap Convert graphics to bitmaps
bitmap Convert everything to bitmaps
SWF Parameters:
SWF layer options:
jpegsubpixels=<pixels> resolution adjustment for jpeg images (same as jpegdpi, but in pixels)
ppmsubpixels=<pixels resolution adjustment for lossless images (same as ppmdpi, but in pixels)
subpixels=<pixels> shortcut for setting both jpegsubpixels and ppmsubpixels
drawonlyshapes convert everything to shapes (currently broken)
ignoredraworder allow to perform a few optimizations for creating smaller SWFs
linksopennewwindow make links open a new browser window
linktarget target window name of new links
linkcolor=<color) color of links (format: RRGGBBAA)
linknameurl Link buttons will be named like the URL they refer to (handy for iterating through links with actionscript)
storeallcharacters don't reduce the fonts to used characters in the output file
enablezlib switch on zlib compression (also done if flashversion>=6)
bboxvars store the bounding box of the SWF file in actionscript variables
dots Take care to handle dots correctly
reordertags=0/1 (default: 1) perform some tag optimizations
internallinkfunction=<name> when the user clicks a internal link (to a different page) in the converted file, this actionscript function is called
externallinkfunction=<name> when the user clicks an external link (e.g. http://www.foo.bar/) on the converted file, this actionscript function is called
disable_polygon_conversion never convert strokes to polygons (will remove capstyles and joint styles)
caplinewidth=<width> the minimum thichness a line needs to have so that capstyles become visible (and are converted)
insertstop put an ActionScript "STOP" tag in every frame
protect add a "protect" tag to the file, to prevent loading in the Flash editor
flashversion=<version> the SWF fileversion (6)
framerate=<fps> SWF framerate
minlinewidth=<width> convert horizontal/vertical boxes smaller than this width to lines (0.05)
simpleviewer Add next/previous buttons to the SWF
animate insert a showframe tag after each placeobject (animate draw order of PDF files)
jpegquality=<quality> set compression quality of jpeg images
splinequality=<value> Set the quality of spline convertion to value (0-100, default: 100).
disablelinks Disable links.
'''
# Convert pdf to swf
if sys.platform == 'linux':
binary = Path(__file__).parent / 'bin' / 'linux' / 'pdf2swf'
elif sys.platform.startswith('win'):
binary = Path(__file__).parent / 'bin' / 'windows' / 'pdf2swf.exe'
else:
print('Render to SWF is only supported on mat and linux')
return
pdf_fp = pdf_render(fp, multi_page=True)
swf_fp = pdf_fp.with_suffix('.swf')
cmd = [
str(binary),
'-s', f'framerate={bpy.context.scene.render.fps}',
# -z, # use zlib
str(pdf_fp),
# '-o', # no need to put output flag
str(swf_fp)
]
subprocess.call(cmd)
# Remove single pdf file
pdf_fp.unlink()
return swf_fp
class GPEXP_OT_export_as_pdf(bpy.types.Operator): class GPEXP_OT_export_as_pdf(bpy.types.Operator):
bl_idname = "gp.export_as_pdf" bl_idname = "gp.export_as_pdf"
@ -103,6 +233,17 @@ class GPEXP_OT_export_as_pdf(bpy.types.Operator):
def poll(cls, context): def poll(cls, context):
return True return True
# multi_page : bpy.props.BoolProperty(name='multi page pdf', default=False)
export_type : bpy.props.StringProperty(name='Export Type', default='pdf_sequence')
@classmethod
def description(cls, context, properties) -> str:
if properties.export_type == 'pdf':
return 'Export layers as individual pdf file (multi-page) using scene range'
elif properties.export_type == 'pdf_sequence':
return 'Export layers as sequence of single-paged pdf file, using scene range'
return 'Export layers as individual SWF files, using scene range'
def execute(self, context): def execute(self, context):
# rd_scn = bpy.data.scenes.get('Render') # rd_scn = bpy.data.scenes.get('Render')
# if not rd_scn: # if not rd_scn:
@ -228,6 +369,7 @@ class GPEXP_OT_export_as_pdf(bpy.types.Operator):
# fo_socket.name isn't right # fo_socket.name isn't right
idx = [i for i in fo_node.inputs].index(fo_socket) idx = [i for i in fo_node.inputs].index(fo_socket)
subpath = fo_node.file_slots[idx].path subpath = fo_node.file_slots[idx].path
fp = Path(fo_node.base_path.rstrip('/')) / subpath fp = Path(fo_node.base_path.rstrip('/')) / subpath
fp = Path(bpy.path.abspath(str(fp)).rstrip("/")) fp = Path(bpy.path.abspath(str(fp)).rstrip("/"))
@ -242,7 +384,14 @@ class GPEXP_OT_export_as_pdf(bpy.types.Operator):
if not l.hide: if not l.hide:
print(f'-> {l.info}') #Dbg print(f'-> {l.info}') #Dbg
pdf_render(fp) if self.export_type == 'pdf_sequence':
pdf_render(fp, multi_page=False)
elif self.export_type == 'pdf':
## TODO: change fp to parent and adapt in pdf render ?
pdf_render(fp, multi_page=self.multi_page)
elif self.export_type == 'swf':
swf_render(fp)
print() print()
### restore ### restore

View File

@ -2,7 +2,7 @@ bl_info = {
"name": "GP Render", "name": "GP Render",
"description": "Organise export of gp layers through compositor output", "description": "Organise export of gp layers through compositor output",
"author": "Samuel Bernou", "author": "Samuel Bernou",
"version": (1, 4, 1), "version": (1, 5, 0),
"blender": (3, 0, 0), "blender": (3, 0, 0),
"location": "View3D", "location": "View3D",
"warning": "", "warning": "",

BIN
bin/linux/pdf2swf Normal file

Binary file not shown.

BIN
bin/windows/pdf2swf.exe Normal file

Binary file not shown.

12
ui.py
View File

@ -249,11 +249,17 @@ class GPEXP_PT_gp_dopesheet_ui(Panel):
layout.prop(bpy.context.preferences.edit, 'use_anim_channel_group_colors') layout.prop(bpy.context.preferences.edit, 'use_anim_channel_group_colors')
layout.separator() layout.separator()
# row.operator('gp.export_as_pdf', icon='RENDER_STILL', text='Render All to PDF Sequences')
layout.label(text='Render All To Vector:')
col= layout.column()
row = col.row(align=True)
row.operator('gp.export_as_pdf', icon='RENDER_STILL', text='PDF Sequences').export_type = 'pdf_sequence'
row.operator('gp.export_as_pdf', icon='RENDER_STILL', text='PDF File').export_type = 'pdf'
col.operator('gp.export_as_pdf', icon='RENDER_STILL', text='SWF File').export_type = 'swf'
row = layout.row()
row.operator('gp.export_as_pdf', icon='RENDER_STILL', text='Render All to PDF Sequences')
if bpy.app.version < (3,0,0): if bpy.app.version < (3,0,0):
row.label(text='Not Blender 3.0.0+') col.label(text='Not Blender 3.0.0+ !')
## Append GP Render workspace (usefull for user with disabled 'load_UI') ## Append GP Render workspace (usefull for user with disabled 'load_UI')
if not bpy.data.workspaces.get('GP Render'): if not bpy.data.workspaces.get('GP Render'):