Fix: Text-Highlights (GlyphRange) in annotierten PDFs sichtbar machen
- merge-annotations.py: rmscene GlyphRange-Blöcke auslesen und als SVG-Rects rendern - Koordinaten: rmscene screen-px × 72/226 → SVG-Punkte (identisch mit rmc-Skalierung) - Farben: fill='rgb(...)' + fill-opacity statt rgba() (Inkscape-Kompatibilität) - Highlights werden VOR Stift-Annotationen eingefügt (korrekte Z-Order) - Dockerfile: rmscene==0.6.1 (rmrl+rmscene>=0.7.0 waren inkompatibel mit rmc)
This commit is contained in:
@@ -9,7 +9,7 @@ RUN apt-get update && apt-get install -y \
|
|||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# rmc + Farb-Patch
|
# rmc + Farb-Patch
|
||||||
RUN pip3 install "rmc==0.3.0" "rmscene>=0.7.0" "pypdf" "rmrl" --break-system-packages --ignore-installed packaging \
|
RUN pip3 install "rmc==0.3.0" "rmscene==0.6.1" "pypdf" --break-system-packages --ignore-installed packaging \
|
||||||
&& python3 - <<'EOF'
|
&& python3 - <<'EOF'
|
||||||
import pathlib
|
import pathlib
|
||||||
import rmc.exporters.writing_tools as m
|
import rmc.exporters.writing_tools as m
|
||||||
|
|||||||
@@ -94,6 +94,46 @@ for i in range(n_pages):
|
|||||||
inner_m = re.search(r'<svg[^>]*>(.*)</svg>', svg, re.DOTALL)
|
inner_m = re.search(r'<svg[^>]*>(.*)</svg>', svg, re.DOTALL)
|
||||||
inner = inner_m.group(1) if inner_m else ''
|
inner = inner_m.group(1) if inner_m else ''
|
||||||
|
|
||||||
|
# GlyphRange-Highlights (Textmarkierungen) aus .rm lesen
|
||||||
|
highlight_svg = ''
|
||||||
|
try:
|
||||||
|
import rmscene
|
||||||
|
RM_SCALE = 72.0 / 226 # rmscene screen-px → SVG-Punkte (wie rmc)
|
||||||
|
HIGHLIGHT_COLORS = {
|
||||||
|
9: ('rgb(255,235,0)', 0.4), # HIGHLIGHT (gelb)
|
||||||
|
3: ('rgb(251,247,25)', 0.4), # YELLOW
|
||||||
|
4: ('rgb(0,255,0)', 0.4), # GREEN
|
||||||
|
5: ('rgb(255,192,203)', 0.4), # PINK
|
||||||
|
6: ('rgb(78,105,201)', 0.4), # BLUE
|
||||||
|
7: ('rgb(179,62,57)', 0.4), # RED
|
||||||
|
}
|
||||||
|
with open(page_rm[i], 'rb') as rmf:
|
||||||
|
blocks = list(rmscene.read_blocks(rmf))
|
||||||
|
for block in blocks:
|
||||||
|
if not (hasattr(block, 'item') and hasattr(block.item, 'value')):
|
||||||
|
continue
|
||||||
|
glyph = block.item.value
|
||||||
|
if not hasattr(glyph, 'rectangles'):
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
color_id = int(glyph.color)
|
||||||
|
except Exception:
|
||||||
|
color_id = 9
|
||||||
|
fill, opacity = HIGHLIGHT_COLORS.get(color_id, ('rgb(255,235,0)', 0.4))
|
||||||
|
for rect in glyph.rectangles:
|
||||||
|
highlight_svg += (
|
||||||
|
f'<rect x="{rect.x * RM_SCALE:.3f}" y="{rect.y * RM_SCALE:.3f}" '
|
||||||
|
f'width="{rect.w * RM_SCALE:.3f}" height="{rect.h * RM_SCALE:.3f}" '
|
||||||
|
f'fill="{fill}" fill-opacity="{opacity}" stroke="none"/>\n'
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
print(f' GlyphRange Fehler: {e}', flush=True)
|
||||||
|
|
||||||
|
# Highlights VOR den Stift-Annotationen einblenden
|
||||||
|
if highlight_svg:
|
||||||
|
print(f' {highlight_svg.count("<rect")} GlyphRect(s) für Seite {i+1}', flush=True)
|
||||||
|
inner = highlight_svg + inner
|
||||||
|
|
||||||
# Annotation-Koordinaten sind in PDF-Punkten
|
# Annotation-Koordinaten sind in PDF-Punkten
|
||||||
# Skalierung: PDF-Punkte -> PNG-Pixel
|
# Skalierung: PDF-Punkte -> PNG-Pixel
|
||||||
pts_to_px = png_w / pdf_w_pt
|
pts_to_px = png_w / pdf_w_pt
|
||||||
|
|||||||
Reference in New Issue
Block a user