Skip to content

Commit

Permalink
Use virtual file instead of temp disk file for renderpage
Browse files Browse the repository at this point in the history
This commit implements image data communication via base64 encoded
string (strongly reducing disk writes).

Currently pdf-tools 'communicates' image data via a tempfile, meaning every time
a page gets rendered, which happens very frequently while selecting
regions (drawing the active region).
  • Loading branch information
dalanicolai committed Dec 20, 2021
1 parent 5880139 commit 36c8e7b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 46 deletions.
29 changes: 18 additions & 11 deletions lisp/pdf-util.el
Original file line number Diff line number Diff line change
Expand Up @@ -620,21 +620,28 @@ See `make-temp-file' for the arguments."
(unless (pdf-util-pdf-window-p window)
(error "Window's buffer is not in PdfView mode")))

(defun pdf-util-munch-file (filename &optional multibyte-p)
;; (defun pdf-util-munch-file (filename &optional multibyte-p)
;; "Read contents from FILENAME and delete it.

;; Return the file's content as a unibyte string, unless MULTIBYTE-P
;; is non-nil."
;; (unwind-protect
;; (with-temp-buffer
;; (set-buffer-multibyte multibyte-p)
;; (insert-file-contents-literally filename)
;; (buffer-substring-no-properties
;; (point-min)
;; (point-max)))
;; (when (and filename
;; (file-exists-p filename))
;; (delete-file filename))))

(defun pdf-util-munch-file (data &optional multibyte-p)
"Read contents from FILENAME and delete it.
Return the file's content as a unibyte string, unless MULTIBYTE-P
is non-nil."
(unwind-protect
(with-temp-buffer
(set-buffer-multibyte multibyte-p)
(insert-file-contents-literally filename)
(buffer-substring-no-properties
(point-min)
(point-max)))
(when (and filename
(file-exists-p filename))
(delete-file filename))))
(base64-decode-string data))

(defun pdf-util-hexcolor (color)
"Return COLOR in hex-format.
Expand Down
48 changes: 13 additions & 35 deletions pymupdf-tq-server/vimura.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import traceback
import getpass
import logging

import base64
import datetime as dt
import time

Expand Down Expand Up @@ -91,32 +93,6 @@ def pagesize(*args):
size = doc[p].mediabox_size
print("OK\n{}:{}\n.".format(size[0], size[1]))

# def renderpage(*args,
# foreground=None,
# background=None,
# highlight_text=None):
# doc = fitz.open(args[0])
# p = doc[int(args[1]) - 1]
# width = int(args[2])
# zoom = width/p.mediabox_size[0]
# mat = fitz.Matrix(zoom, zoom)
# pix = p.get_pixmap(matrix=mat)
# tmpfile = "/tmp/tmpimg"

# pix.save(tmpfile)

# if highlight_text:
# with Image.open(tmpfile) as im:
# draw = ImageDraw.Draw(im, 'RGBA')
# edges = denormalize_edges(p,
# [float(i)*zoom
# for i in highlight_text.split()])
# draw.rectangle(edges, fill=(128,128,128,128)) # foreground is lighter

# im.save(tmpfile, "PNG")

# print("OK\n{}\n.".format(tmpfile))

def renderpage(*args,
foreground=None,
background=None,
Expand All @@ -138,7 +114,8 @@ def renderpage(*args,
zoom = width/p.mediabox_size[0]
mat = fitz.Matrix(zoom, zoom)
pix = p.get_pixmap(matrix=mat)
tmpfile = "/tmp/tmpimg"
# tmpfile = "/tmp/tmpimg"
im_data = pix.tobytes()

if highlight_text or highlight_region or draw_line:
image_data = pix.tobytes()
Expand Down Expand Up @@ -170,16 +147,17 @@ def renderpage(*args,
else:
draw.rectangle(list(r), fill=(128, 128, 128, 128))

im.save(tmpfile, "PNG")
else:
pix.save(tmpfile)
im_bytes = io.BytesIO()
im.save(im_bytes, "PNG")
im_data = im_bytes.getvalue()

im_data64 = base64.b64encode(im_data).decode()

print("OK\n{}\n.".format(tmpfile))
print("OK\n{}\n.".format(im_data64))

def getselection(*args):
p = doc[int(args[1]) - 1]
if args[2] == "0 0 1 1":
def getselection(filepath, real_pn, rect, style):
p = doc[int(real_pn) - 1]
if rect == "0 0 1 1":
size = p.mediabox_size
selections = [[str(j[i]/size[0])
if i in [0, 2]
Expand All @@ -189,7 +167,7 @@ def getselection(*args):
selections_formatted = "\n".join([" ".join(j) for j in selections])
print("OK\n{}\n.".format(selections_formatted))
else:
print("OK\n{}\n.".format(args[2]))
print("OK\n{}\n.".format(rect))

def get_text_line(text, word):
line_text = ""
Expand Down

0 comments on commit 36c8e7b

Please sign in to comment.