---
id: 2026-04-16T12:55:49-0400
title: 2026-04-16 12:55:49
tags:
  - status/draft
date-created: 2026-04-16T12:55:49-04:00
daily: "[[2026-04-16]]"
---
# 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.
