Showing posts with label Spotlighters. Show all posts
Showing posts with label Spotlighters. Show all posts

Friday, August 28, 2026

Relayering the onion for PDF reversal from ODG to Scribus

 You can make a layered PDF from a LibreOffice drawing, at least obliquely.

Exporting to PDF from LO does not capture the layers in the source as PDG 1.6 layers.

Opening with Scribus, then exporting to a layered PDF works. But. The layers go from left-to-right as top-to-bottom, rather than right-to-left. Later added layers end up on top, and if they are a scanned image, everything below gets masked.








Tip of the tam-o-shanter:




Original layer order in the Scribus-based PDF export:



BEFORE


Just a little line cut and pasts. Viola!


$ diff  the-madison-floorplan+poi-feet.fodg the-madison-floorplan+poi-feet-regrooved.fodg
726,729d725
<    <draw:layer draw:name="Main Halls + Rooms"/>
<    <draw:layer draw:name="Building Columns"/>
<    <draw:layer draw:name="Fire+Exit"/>
<    <draw:layer draw:name="Closets"/>
730a727,730
>    <draw:layer draw:name="Closets"/>
>    <draw:layer draw:name="Fire+Exit"/>
>    <draw:layer draw:name="Building Columns"/>
>    <draw:layer draw:name="Main Halls + Rooms"/>
1925c1925
< </office:document>
\ No newline at end of file
---
> </office:document>

FODG is your friend!

AFTER


Wednesday, June 10, 2026

Delaminating the Onion, OGR style

 After I learned about geospatial PDF documents with layers of GIS "goo" embedded I've tried out maps and similar graphics for events and travel. New challenge--having a layered PDF for a theater stage floor plan. The idea came when I found first one, then a different paper drawing, detailed but lacking those "mechanical drawing" features such as a title block, date, scale, source, things like that.

New version, showing 3 of 8 layers


The old drawings could have come from Corel Draw for all I know.


I wanted to use LibreOffice Draw if possible, to create a layered PDF, as I've learned how to do most of what I could do with MS Visio. The above image is the fix for dimensions in Imperial units that show up as "10.01 feet" for unknown reasons. Truncating to 1 decimal place makes it better as "10.0 feet."

Here's one with a rounding error, and also a scaling error as the scale "rod" should be 10 feet, not 9 and a half-ish.

The ODG, seat numbers and scan layers were supposed to have boxes to check if that layer was included in the view. 

But no, while the LibreOffice drawing can manage internal layer juggling, writing a PDF with defined layers does not work.

https://bugs.documentfoundation.org/show_bug.cgi?id=138142

Bug 138142 - "Draw should have an option to export to PDF keeping separate layers"

A workaround posted here:

https://graphicdesign.stackexchange.com/questions/169487/how-to-export-a-drawing-odg-file-from-libreoffice-25-8-to-a-multi-layered-pdf-f 

Load the ODG file into Scribus, then export to a layered PDF. It works, but only to a degree, as the layers get shuffled and renamed.

Extra layers can be added in Scribus, so I chose to do the measured baselines (aisles etc.) in ODG and the icing of title blocks and guides for lining out skewed scanned of paper drawings in Scribus.

I've also added an SVG layer from Inkscape.

Looking at an imported JPEG is awful from Scribus. But the PDF looks fine.

Layers and more


Almost had an issue with "back-loading" a Scribus file on Windows 1.6, after creating a document in NetBSD with 1.7. So I'll use the higher version and save as" a lower if anyone needs to look for themselves.



The scans ended up slightly different in shape, added to the task of alignment.

 

Embellishing with seat designs and numbers in Inkscape turned out to be a bigger task than imagined. For one thing, the web site has a dark theme, but printing the images for human note-taking needs a light theme, as these are.

The seat counts differ between the two, I finally noticed also.


Saturday, April 4, 2026

Key flipping from sheet to form

 After I wrangled 2 spreadsheets (and 1 Google sheet) into database tables, my first picks for primary keys needed to be changed based on how the data were and how I wanted things to be.

Whoever did the manual entry into rows and columns used month and year as the key separators, since the events were generally produced every month (for literal decades). So it made sense that the first attempt used these as keys. I don't like to use a serial number key for tasks like this as part of the outcome should be normalizing the data; getting an error message that there are duplicate months in a year needs to be investigated.

Among other things I found were complete cast/crew duplicates for 1 show that ran for 2 months (others had only ditto marks, making them easier to spot and tidy up). I needed to switch from a monthly key to a sequence value because after 2000, the shows were scheduled for several week runs but not staying within a month. And there were weekend shows, plus multi-play productions in single ticket access.

 References at the end, one LibreOffice and two DBA Stack Exchange

I started with this key: 

   primary key (year_str, month_str, production, director, person, role)

 The year and month are strings, instead of integers because there were originally a variety of formats which I fixed after initial load.

The propose change: 

ALTER TABLE cast_cooked DROP CONSTRAINT cast_cooked_pkey;
ALTER TABLE cast_cooked ADD PRIMARY KEY (season, sequence, production, person, role, band_cast_crew);

 

Using the example questions, I deleted duplicate rows as I found them, mainly trial-and-error because the first line above always works and the second only when all dupes are clear.

I was overzealous in thinking I should include what turned out to be an indistinct key:

psql:alter_key.sql:3: ERROR:  constraint "cast_cooked_pkey" of relation "cast_cooked" does not exist

psql:alter_key.sql:4: ERROR:  column "sub_seq" of relation "cast_cooked" contains null values

 

All nulls are the same, not unique. Turns out this key also messed with LibreOffice forms, as mismatched tables showed no rows in one (scary!). Had to be removed from the primary key, or filled somehow; I chose the former as faster.

 

ALTER TABLE
psql:alter_key.sql:4: ERROR:  could not create unique index "cast_cooked_pkey"
DETAIL:  Key (season, sequence, sub_seq, person, role)=(4, 11, C, First Last, Director) is duplicated.


These were usually easy, except for the 44 rows of cast+crew dupes, and then one complete duplicate (don't ask).

db=> delete  from cast_cooked where season = 12 and sequence = 7 and month_str = '5' ;

DELETE 44

 
A simple statement but should be sanity claused.

Drop the table constraint and retry:

psql:alter_key.sql:3: ERROR:  constraint "cast_cooked_pkey" of relation "cast_cooked" does not exist

psql:alter_key.sql:4: ERROR:  could not create unique index "cast_cooked_pkey"

DETAIL:  Key (season, sequence, production, person, role, band_cast_crew)=(26, 3, Scrooge (shocking), First Last, Director, crew) is duplicated.


 db=>  select * from cast_cooked where season = 26 and sequence = 3 and role = 'Director' order by month_str, person;
  year_str  | month_str  |     production     |    director     |     person      |   role   | band_cast_crew | season | sequence | opening | closing | sub_seq
------------+------------+--------------------+-----------------+-----------------+----------+----------------+--------+----------+---------+---------+---------
 87         | 12         | Scrooge (shocking) | First Last| First Last  | Director | crew           |     26 |        3 |         |         |
 87         | 12         | Scrooge (shocking) | Firss Last| First Last | Director | crew           |     26 |        3 |         |         |

 There was another typo I redacted, duplicated, as director was not a key value.

To remove a duplicate you might need a "ROW ID" which in PostgreSQL acts like this:

db => select ctid from cast_cooked where season = 26 and sequence = 3 and role = 'Director' order by month_str, person;
  ctid
--------
 (5,14)
 (5,30)
(2 rows)

db=> delete  from cast_cooked where season = 26 and sequence = 3 and role = 'Director' and ctid = '(5,30)';
DELETE 1
 

Then the anticlimactic "done" success message (along with the "you already did that" warning).

 db=> \i alter_key.sql
psql:alter_key.sql:3: ERROR:  constraint "cast_cooked_pkey" of relation "cast_cooked" does not exist
ALTER TABLE

db=>

 

And now, better queries!


 

Two-step also:


 

~ ~ ~

References:

https://books.libreoffice.org/en/BG72/BG7204-Forms.html#toc41
https://dba.stackexchange.com/questions/138320/duplicate-rows-how-to-remove-one
https://dba.stackexchange.com/questions/159793/how-to-set-a-not-null-column-into-null-in-postgresql

 

Monday, February 2, 2026

Shrinking and wrapping the copyrights to own imagery

The new web site is "responsive" or so they say. Large images are sliced and diced into smaller versions for display on a small device window, saving load time. The smarty-pants part is it figuring out your screen across the board.

Checking what was viewable and what the image tags looked like, I grabbed a bunch  / with a tip of the sombrero to online:

https://stackoverflow.com/questions/4602153/how-do-i-use-wget-to-download-all-images-into-a-single-folder-from-a-url

$ ls -l *rocky*

spot lighters   77360 Jun 20  2025 6855cb[*]_rocky horror_9235210_orig-p-500.jpg

spot lighters  211763 Jun 20  2025 6855cb[*]_rocky horror_9235210_orig.jpg

I used the A list "ico, SVG, svg, jpeg, jpg, bmp, gif, png, heic" but no SVG came through. And PDF failed in a robotic way.

The p-500 means the file got downsized by the automat to fit in a 500-pixel holey window.

$ exiftool *rocky* | egrep "^File Size|^Image Size"
File Size                       : 76 KiB
Image Size                      : 500x752

File Size                       : 207 KiB
Image Size                      : 532x800

Cut about 2/3 in size for only 500 pixels versus 532.

One has the tags I embossed, at least on the largest chunk.

  31698 Dec 21 01:00 69473f12[*]0c_D48a-p-500.jpg
  68603 Dec 21 01:00 69473f12[*]0c_D48a-p-800.jpg
  81388 Dec 21 01:00 69473f12[*]0c_D48a.jpg

PDF tag? sure, why not.

$ strings *D48* | grep -i spath
  <pdf:Author>Jim Spath</pdf:Author>
$ strings *D48*500* | grep -i spath
$ strings *D48*800* | grep -i spath

On the other site, images over 2000 pixels wide get de-tagged.

Spotlighters-Purchase-Tickets-Icon_Ticket-2.jpg
Your image was automatically resized to 2000x1085 pixels. 

Spotlighters-Logo.jpg
Your image was automatically resized to 2000x882 pixels. 

Once that happens, the tell-tale is a different processor. I'm guessing GD beneath, maybe Python middleware?

$ jhead  Spotlighters_Purchase_Tickets_Icon.jpg
File name    : Spotlighters_Purchase_Tickets_Icon.jpg
File size    : 126559 bytes
File date    : 2026:01:31 22:13:11
Resolution   : 2000 x 1085
JPEG Quality : 75
Comment      : CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), default quality

Fixer upper: 

$ time exiftool   -author="Art Ist"   -copyright="CC BY-NC-SA 4.0 Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International This work is licensed under CC BY-NC-SA 4.0. To view a copy of this license, visit https://creativecommons.org/licenses/by-nc-sa/4.0/" -subject="Art"    -title="For Spotlighters"  -datetime="2026-01-31 00:00:00"  Logo-2000x882.jpg
    1 image files updated

What else?
 Oh, yah. Pictures or it didn't happen.



Still looking for where I snipped off the orientation.


Sunday, January 11, 2026

Note to Self, Mainly, on Shrinking Map Colors

 I am helping a theatre redo their website, from a post-Y2K relic to one that promises responsiveness (their phrase). They make a big deal about putting warning flags on images over 1MB, or a certain pixel size (like 800x1340). On the "directions and parking" section the old site had text directions, probably copied from Mapquest in 2002 or so. I kept the narrative and added static maps, since I didn't want to try a "live" google map image, figuring most folks would put the address in the own GPS/map app.

  The OSMAND app works great, so I figured I'd do screenshots and show the suggested routes, whether they lined up with the old text or not. They looked good, full screen PNG files with nice colors. Only they ended up way too big for a quick page load.

-rw-rw-rw-  1 user  users  1586661 Dec 14 22:19 map_from_westminster.png

When I saved them as JPEG, they didn't shrink much, just got a little fuzzier. Smaller size images didn't look great either. So I turned to the old standby library of graphics fixer-uppers, NetPBM [ netpbm.sourceforge.net/doc/ ]

The classic set of 216 colors (AKA "Web Safe") made sense as a target palette, as long as the altered image looked decent. I recall doing color reduction in the past and making some pictures that didn't. The docs said create a palette file, like so:

pamseq 3 5 >websafe.pam

Now, I had a 3 color band file, 5 values deep, just like Netscape likes. Applying that to a large image took almost no time:

pnmremap -map=websafe.pam map_from_westminster.pnm >websafe_west.ppm

Note this skips the PNG to PNM and PPM to PNG steps, which I added in a shell script that rotated through the 8 compass points of map/directions I wanted (N, NE, E, etc.)

#!/bin/sh

for img in \

 img1 \

 img2 \


do

  pngtopnm $img.png >$img.pnm

  pnmremap -map=websafe.pam $img.pnm | pnmtopng > ${img}_c216.png

done


Even on a slow drive, this is quick.

$ time pngtopnm map_from_westminster.png | pnmremap -map=websafe.pam - | pnmtopng >west_c26.png
pnmremap: 216 colors found in colormap

real    0m0.246s
user    0m0.260s
sys     0m0.017s

$ ls -l west_c26.png
-rw-r--r--  1 user  users  282243 Jan 12 00:01 west_c26.png


From 1.5 MB to 276 KB: good shrink!


$ perl $EXIFTOOL *west* | egrep "File Size|Image Size|Color Type"
File Size                       : 1549 KiB
Color Type                      : RGB
Image Size                      : 800x1340
File Size                       : 276 KiB
Color Type                      : Palette
Image Size                      : 800x1340

Afterward, I reapplied metadata such as Author and Copyright to the PNG file with the awesome exiftool.

Yet to do: add an overlay showing the OpenStreetMap sources used.