Skip to content

Commit

Permalink
Minor fixes/improvements of upload_image.py (#2449)
Browse files Browse the repository at this point in the history
### What

Lessons learned from #2440

- On Mac, PIL's clipboard import compresses to JPG, which is bad =>
added a custom function to use PNG instead.
- Tuned the PIL image saving parameters to optimise for file size
- Added some pngcrush CLI parameter for optimisation
- Discard pngcrush output if it ends up bigger than output (PIL's PNG
export is pretty good in most cases it seems)

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [ ] ~~I've included a screenshot or gif (if applicable)~~

<!-- This line will get updated when the PR build summary job finishes.
-->
PR Build Summary: https://build.rerun.io/pr/2449

<!-- pr-link-docs:start -->
Docs preview: https://rerun.io/preview/8563e84/docs
Examples preview: https://rerun.io/preview/8563e84/examples
<!-- pr-link-docs:end -->
  • Loading branch information
abey79 authored and emilk committed Jun 15, 2023
1 parent 1c95e21 commit 212d5d0
Showing 1 changed file with 47 additions and 7 deletions.
54 changes: 47 additions & 7 deletions scripts/upload_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import mimetypes
import os
import shutil
import subprocess
import sys
import tempfile
from io import BytesIO
Expand All @@ -55,6 +56,37 @@
]


def image_from_clipboard() -> Image:
"""
Get image from the clipboard.
On Mac, `PIL.ImageGrab.grabclipboard()` compresses to JPG. This function uses the same code but uses PNG instead.
"""
if sys.platform == "darwin":
fh, filepath = tempfile.mkstemp(".png")
os.close(fh)
commands = [
'set theFile to (open for access POSIX file "' + filepath + '" with write permission)',
"try",
" write (the clipboard as «class PNGf») to theFile",
"end try",
"close access theFile",
]
script = ["osascript"]
for command in commands:
script += ["-e", command]
subprocess.call(script)

im = None
if os.stat(filepath).st_size != 0:
im = PIL.Image.open(filepath)
im.load()
os.unlink(filepath)
return im
else:
return PIL.ImageGrab.grabclipboard()


class Uploader:
def __init__(self, pngcrush: bool):
gcs = storage.Client("rerun-open")
Expand All @@ -69,8 +101,6 @@ def upload_file(self, path: Path) -> str:
----------
path : Path
The path to the file to upload.
pngcrush : bool
Whether to run pngcrush on the file before uploading.
Returns
-------
Expand Down Expand Up @@ -128,7 +158,8 @@ def upload_stack_from_clipboard(self, name: str) -> str:
str
The `<picture>` tag for the image stack.
"""
clipboard = PIL.ImageGrab.grabclipboard()

clipboard = image_from_clipboard()
if isinstance(clipboard, PIL.Image.Image):
image = clipboard
return self.upload_stack(
Expand Down Expand Up @@ -188,7 +219,7 @@ def upload_stack(
# upload images
for name, width, image in image_stack:
with BytesIO() as buffer:
image.save(buffer, output_format)
image.save(buffer, output_format, optimize=True, quality=80, compress_level=9)
image_data = buffer.getvalue()

digest = data_hash(image_data)
Expand Down Expand Up @@ -254,11 +285,20 @@ def run_pngcrush(data: bytes) -> bytes:
input_file.write_bytes(data)

output_file = Path(tmpdir) / "output.png"
os.system(f"pngcrush -q -warn {input_file} {output_file}")
os.system(f"pngcrush -q -warn -rem allb -reduce {input_file} {output_file}")
output_data = output_file.read_bytes()

logging.info(f"pngcrush reduced size from {len(data)} to {len(output_data)} bytes")
return output_data
input_len = len(data)
output_len = len(output_data)
if output_len > input_len:
logging.info("pngcrush failed to reduce file size")
return data
else:
logging.info(
f"pngcrush reduced size from {input_len} to {output_len} bytes "
f"({(input_len - output_len) *100/ input_len:.2f}%)"
)
return output_data


def data_hash(data: bytes) -> str:
Expand Down

0 comments on commit 212d5d0

Please sign in to comment.