use image::ColorType;
use pdf_writer::types::{
ActionType, AnnotationType, MediaClipType, RenditionOperation, RenditionType,
TempFileType,
};
use pdf_writer::{Content, Filter, Finish, Name, Pdf, Rect, Ref, Str, TextStr};
fn get_bbox(page: &Rect, mut w: f32, mut h: f32) -> Rect {
if w > (page.x2 - page.x1) {
let f = (page.x2 - page.x1) / w;
w *= f;
h *= f;
}
if h > (page.y2 - page.y1) {
let f = (page.y2 - page.y1) / h;
w *= f;
h *= f;
}
Rect::new(
(page.x2 - w) / 2.0,
(page.y2 - h) / 2.0,
(page.x2 + w) / 2.0,
(page.y2 + h) / 2.0,
)
}
fn main() -> std::io::Result<()> {
let embedded = true;
let mut pdf = Pdf::new();
let catalog_id = Ref::new(1);
let page_tree_id = Ref::new(2);
let page_id = Ref::new(3);
let annotation_id = Ref::new(4);
let video_file_id = Ref::new(5);
let form_xobject_id = Ref::new(6);
let image_id = Ref::new(7);
let image_name = Name(b"Im1");
pdf.catalog(catalog_id).pages(page_tree_id);
pdf.pages(page_tree_id).kids([page_id]).count(1);
let mut page = pdf.page(page_id);
let a4_landscape = Rect::new(0.0, 0.0, 842.0, 595.0);
page.media_box(a4_landscape);
page.parent(page_tree_id);
page.annotations([annotation_id]);
page.finish();
let data = std::fs::read("examples/bear-1280x720.jpg").unwrap();
let dynamic = image::load_from_memory(&data).unwrap();
assert!(dynamic.color() == ColorType::Rgb8);
let mut image = pdf.image_xobject(image_id, &data);
image.filter(Filter::DctDecode);
image.width(dynamic.width() as i32);
image.height(dynamic.height() as i32);
image.color_space().device_rgb();
image.bits_per_component(8);
image.finish();
let bbox = get_bbox(&a4_landscape, dynamic.width() as f32, dynamic.height() as f32);
let mut content = Content::new();
content.save_state();
content.transform([
(bbox.x2 - bbox.x1),
0.0,
0.0,
(bbox.y2 - bbox.y1),
bbox.x1,
bbox.y1,
]);
content.x_object(image_name);
content.restore_state();
let content_data = content.finish();
let mut form_xobject = pdf.form_xobject(form_xobject_id, &content_data);
form_xobject.bbox(bbox);
form_xobject.resources().x_objects().pair(image_name, image_id);
form_xobject.finish();
let file_path = std::fs::canonicalize("examples/bear-1280x720.mp4").unwrap();
let file_name = file_path.file_name().unwrap();
if embedded {
let data = std::fs::read(&file_path).unwrap();
pdf.embedded_file(video_file_id, &data);
}
let mut annotation = pdf.annotation(annotation_id);
annotation.subtype(AnnotationType::Screen);
annotation.rect(bbox);
annotation.page(page_id);
annotation.appearance().normal().stream(form_xobject_id);
let mut action = annotation.action();
action.action_type(ActionType::Rendition);
action.operation(RenditionOperation::Play);
action.annotation(annotation_id);
let mut rendition = action.rendition();
rendition.subtype(RenditionType::Media);
let mut media_clip = rendition.media_clip();
media_clip.subtype(MediaClipType::Data);
if embedded {
media_clip
.data()
.path(Str(file_name.as_encoded_bytes()))
.embedded_file(video_file_id);
} else {
let file_url = &[b"file://", file_path.as_os_str().as_encoded_bytes()].concat();
media_clip.data().file_system(Name(b"URL")).path(Str(file_url));
}
media_clip.data_type(Str(b"video/mp4"));
media_clip.permissions().temp_file(TempFileType::Access);
media_clip.alt_texts([TextStr(""), TextStr("default text")]);
media_clip.finish();
rendition.media_play_params().controls(true);
rendition.finish();
action.finish();
annotation.finish();
std::fs::write("target/video.pdf", pdf.finish())
}