vault backup: 2026-04-16 17:07:54
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
---
|
||||
id: 2026-04-16T12:55:49-04:00
|
||||
aliases: []
|
||||
title: 2026-04-16 12:55:49
|
||||
tags:
|
||||
- authorship/original
|
||||
- destiny/permanent
|
||||
- status/draft
|
||||
- type/periodic/timestamped
|
||||
dg-publish: true
|
||||
date-created: 2026-04-16T12:55:49-04:00
|
||||
daily: "[[2026-04-16]]"
|
||||
weekly: "[[2026-W16]]"
|
||||
monthly: "[[2026-04]]"
|
||||
quarterly: "[[2026-Q2]]"
|
||||
yearly: "[[2026]]"
|
||||
---
|
||||
# 2026-04-16 12:55:49
|
||||
|
||||
## Batch Creating Bluebeam Revu Length Measure Annotations
|
||||
|
||||
I've been trying for years now
|
||||
to figure out how to batch create PDF markups
|
||||
understood by the Bluebeam Revu as length measurements.
|
||||
|
||||
The most practical route I've found so far
|
||||
is to batch create polyline annotations through a PDF editing library,
|
||||
export these markups to Revu's XML based .bax format,
|
||||
edit the XML, then reimport the modified .bax file.
|
||||
|
||||
### Converting a Polyline to a Bluebeam Polylength
|
||||
|
||||
#### Export Markups
|
||||
|
||||
Below is a .bax file for a single-page letter-sized PDF document
|
||||
with only two markups,
|
||||
one standard polyline,
|
||||
and one polylength measurement.
|
||||
|
||||
```
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Document Version="1">
|
||||
<Page Index="0">
|
||||
<Label>1</Label>
|
||||
<Width>612</Width>
|
||||
<Height>792</Height>
|
||||
<Annotation>
|
||||
<Page>1</Page>
|
||||
<Contents />
|
||||
<ModDate>2026-04-16T10:34:28.0000000Z</ModDate>
|
||||
<Color>#FF0000</Color>
|
||||
<Type>PolyLine</Type>
|
||||
<ID>QYMFSTEOUXIEHCPW</ID>
|
||||
<TypeInternal>Bluebeam.PDF.Annotations.AnnotationPolyline</TypeInternal>
|
||||
<Raw>789c<!--HEX TRUNCATED--></Raw>
|
||||
<Index>0</Index>
|
||||
<Subject>PolyLine</Subject>
|
||||
<CreationDate>2026-04-16T10:34:28.0000000Z</CreationDate>
|
||||
<Author>zmeyers</Author>
|
||||
</Annotation>
|
||||
<Annotation>
|
||||
<Page>1</Page>
|
||||
<Contents>15'-7"</Contents>
|
||||
<ModDate>2026-04-16T10:35:00.0000000Z</ModDate>
|
||||
<Color>#FF0000</Color>
|
||||
<Type>PolyLine</Type>
|
||||
<ID>BMHFFZSZURMLPTRN</ID>
|
||||
<TypeInternal>Bluebeam.PDF.Annotations.AnnotationMeasurePolylength</TypeInternal>
|
||||
<Raw>789cad92d<!--HEX TRUNCATED--></Raw>
|
||||
<Index>1</Index>
|
||||
<Subject>Polylength Measurement</Subject>
|
||||
<CreationDate>2026-04-16T10:34:50.0000000Z</CreationDate>
|
||||
<Author>zmeyers</Author>
|
||||
</Annotation>
|
||||
<Scale>
|
||||
<Page>1</Page>
|
||||
<ID>RKEGIABVKDXPBWJP</ID>
|
||||
<Raw>789c<!--HEX TRUNCATED--></Raw>
|
||||
<Ratio>0.25 in = 1 ft' in"</Ratio>
|
||||
<Index>-1</Index>
|
||||
<X1>0</X1>
|
||||
<Y1>0</Y1>
|
||||
<X2>612</X2>
|
||||
<Y2>792</Y2>
|
||||
</Scale>
|
||||
</Page>
|
||||
<GlobalResources>
|
||||
<Resource>
|
||||
<ID>789cf37<!--HEX TRUNCATED--></Raw>
|
||||
</Resource>
|
||||
<Resource>
|
||||
<ID>789c<!--HEX TRUNCATED--></ID>
|
||||
<Raw>789c<!--HEX TRUNCATED--></Raw>
|
||||
</Resource>
|
||||
</GlobalResources>
|
||||
</Document>
|
||||
```
|
||||
|
||||
#### Change `<TypeInternal>`
|
||||
|
||||
Change the `<TypeInternal>` property of the polyline
|
||||
from `Bluebeam.PDF.Annotations.AnnotationPolyline`
|
||||
to `Bluebeam.PDF.Annotations.AnnotationMeasurePolylength`
|
||||
|
||||
#### Change `<Raw>`
|
||||
|
||||
##### Decode and Decompress
|
||||
|
||||
Decode and decompress the value of the `<Raw>` property.
|
||||
|
||||
> [!info]
|
||||
> The standard header `789c`
|
||||
> indicates the data is zlib-compressed binary,
|
||||
> encoded as hexadecimal.
|
||||
|
||||
```python
|
||||
# decompress_hex.py
|
||||
import zlib
|
||||
import binascii
|
||||
import sys
|
||||
|
||||
raw_hex = sys.argv[1]
|
||||
|
||||
data = binascii.unhexlify(raw_hex)
|
||||
decompressed = zlib.decompress(data)
|
||||
|
||||
print(decompressed)
|
||||
```
|
||||
|
||||
The resultant text is a PDF object
|
||||
resembling the following:
|
||||
|
||||
```pdf
|
||||
<</Vertices[161.8211 574.2108 279.8409 669.1133 407.5944 594.2863]/IC[1 0 0]/T(zmey...>>
|
||||
```
|
||||
|
||||
##### Modify the Object
|
||||
|
||||
Insert the following key-value pair:
|
||||
|
||||
```
|
||||
/Measure/BBObjPtr_XXXXXXXXXXXXXXXX
|
||||
```
|
||||
|
||||
where `XXX...` is the name of the Scale object.
|
||||
It may be most straightforward to copy this key-value pair
|
||||
from a manually created length measurement on the same page.
|
||||
|
||||
##### Recompress and Reencode
|
||||
|
||||
```python
|
||||
# compress_to_hex.py
|
||||
import zlib
|
||||
import binascii
|
||||
import sys
|
||||
|
||||
text = sys.argv[1]
|
||||
compressed = zlib.compress(text.encode('utf-8'))
|
||||
hex_encoded = binascii.hexlify(compressed).decode('ascii')
|
||||
|
||||
print(hex_encoded)
|
||||
```
|
||||
|
||||
Replace the old value of `<Raw>` with the modified hex.
|
||||
|
||||
#### Reimport Markups
|
||||
|
||||
In the target PDF,
|
||||
open the markup summary,
|
||||
delete all markups,
|
||||
then reimport.
|
||||
Reference in New Issue
Block a user