here is the code i have to date.
from PIL import Image
import requests
from io import BytesIO
import numpy as np
import logging
import sys
import holoviews as hv
from holoviews import opts
from holoviews import streams
import panel as pn
pn.extension(sizing_mode='stretch_both')
pn.extension('terminal')
hv.extension('bokeh')
FORMAT = "** %(asctime)s | %(levelname)s | %(name)s | %(message)s"
def reconfig_basic_config(format_=FORMAT, level=logging.INFO):
"""(Re-)configure logging"""
logging.basicConfig(format=format_, level=level, force=True)
logging.info("Logging.basicConfig completed successfully")
reconfig_basic_config()
logger = logging.getLogger(name="app")
def box_cropper(bounds):
if bounds is None:
b = hv.Rectangles((0, 0, 0, 0))
else:
b = hv.Rectangles(bounds)
b.opts(alpha=0.3, line_color='red')
info = imagev._get_selection_expr_for_stream_value(bounds=bounds)
(dim_expr, bbox, region_element) = info
logger.info(bbox)
if bbox:
cartesian = {"x0": bbox["x"][0], "y0": abs(bbox["y"][1]), "x1": bbox["x"][1], "y1": abs(bbox["y"][0])}
logger.info(f"cartesian = {cartesian}")
# Define the crop box (left, upper, right, lower)
crop_box = (cartesian["x0"], cartesian["y0"], cartesian["x1"], cartesian["y1"]) # You can change these values
logger.info(f"crop_box = {crop_box}")
cropped_image = theimage.crop(crop_box)
logger.info(f"cropped_image.size={cropped_image.size}")
**# how to return and display this image in a separate plot in a different pn.Row, pn.Column**
** # image_crop = hv.Image(np.array(cropped_image))**
return b
url = "https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/%D0%9F%D0%BE%D1%80%D1%82%D1%80%D0%B5%D1%82_%D0%BE%D0%BB%D0%B5%D0%BD%D1%8F.jpg/500px-%D0%9F%D0%BE%D1%80%D1%82%D1%80%D0%B5%D1%82_%D0%BE%D0%BB%D0%B5%D0%BD%D1%8F.jpg"
response = requests.get(url)
theimage = Image.open(BytesIO(response.content))
(w,h) = theimage.size
logger.info(f"w={w} h={h}")
bounds=(0,-h,w,0) # Coordinate system: (left, bottom, right, top)
imagev = hv.Image(np.array(theimage), bounds=bounds)
main_style1 = [''' :host { overflow-y: scroll; } ''']
raw_css = [''' #main { background-color:white; padding: 0px !important; } ''']
xy_stream = hv.streams.BoundsXY()
dmap_cropper = hv.DynamicMap(box_cropper, streams=[xy_stream])
w_container = imagev.opts(cmap='gray',responsive=True, tools=["box_select"], active_tools=["box_select"]) * dmap_cropper
image_viewer = pn.Column(w_container, min_height=h)
template = pn.template.FastListTemplate(
title="Image Browser - Select n Copy/Crop" ,
sidebar=[],
main=[image_viewer],
collapsed_sidebar=True,
raw_css=raw_css
)
template.servable();