示例#1
0
def _marshall_av_media(coordinates, proto, data, mimetype):
    """ Fill audio or video proto based on contents of data.

    Given a string, check if it's a url; if so, send it out without modification.
    Otherwise assume strings are filenames and let any OS errors raise.

    Load data either from file or through bytes-processing methods into a
    MediaFile object.  Pack proto with generated Tornado-based URL.
    """
    # Audio and Video methods have already checked if this is a URL by this point.

    if isinstance(data, str):
        # Assume it's a filename or blank.  Allow OS-based file errors.
        with open(data, "rb") as fh:
            this_file = media_file_manager.add(fh.read(), mimetype,
                                               coordinates)
            proto.url = this_file.url
            return

    if data is None:
        # Allow empty values so media players can be shown without media.
        return

    # Assume bytes; try methods until we run out.
    if isinstance(data, bytes):
        pass
    elif isinstance(data, io.BytesIO):
        data.seek(0)
        data = data.getvalue()
    elif isinstance(data, io.RawIOBase) or isinstance(data, io.BufferedReader):
        data.seek(0)
        data = data.read()
    elif type_util.is_type(data, "numpy.ndarray"):
        data = data.tobytes()
    else:
        raise RuntimeError("Invalid binary data format: %s" % type(data))

    this_file = media_file_manager.add(data, mimetype, coordinates)
    proto.url = this_file.url
def marshall_images(
    image, caption, width, proto_imgs, clamp, channels="RGB", format="JPEG"
):
    channels = channels.upper()

    # Turn single image and caption into one element list.
    if type(image) is list:
        images = image
    else:
        if type(image) == np.ndarray and len(image.shape) == 4:
            images = _4d_to_list_3d(image)
        else:
            images = [image]

    if type(caption) is list:
        captions = caption
    else:
        if isinstance(caption, str):
            captions = [caption]
        # You can pass in a 1-D Numpy array as captions.
        elif type(caption) == np.ndarray and len(caption.shape) == 1:
            captions = caption.tolist()
        # If there are no captions then make the captions list the same size
        # as the images list.
        elif caption is None:
            captions = [None] * len(images)
        else:
            captions = [str(caption)]

    assert type(captions) == list, "If image is a list then caption should be as well"
    assert len(captions) == len(images), "Cannot pair %d captions with %d images." % (
        len(captions),
        len(images),
    )

    proto_imgs.width = width
    for image, caption in zip(images, captions):
        proto_img = proto_imgs.imgs.add()
        if caption is not None:
            proto_img.caption = str(caption)

        # PIL Images
        if isinstance(image, ImageFile.ImageFile) or isinstance(image, Image.Image):
            data = _PIL_to_bytes(image, format)

        # BytesIO
        elif type(image) is io.BytesIO:
            data = _BytesIO_to_bytes(image)

        # Numpy Arrays (ie opencv)
        elif type(image) is np.ndarray:
            data = _verify_np_shape(image)
            data = _clip_image(data, clamp)

            if channels == "BGR":
                if len(data.shape) == 3:
                    data = data[:, :, [2, 1, 0]]
                else:
                    raise StreamlitAPIException(
                        'When using `channels="BGR"`, the input image should '
                        "have exactly 3 color channels"
                    )

            data = _np_array_to_bytes(data, format=format)

        # Strings
        elif isinstance(image, str):
            # If it's a url, then set the protobuf and continue
            try:
                p = urlparse(image)
                if p.scheme:
                    proto_img.url = image
                    continue
            except UnicodeDecodeError:
                pass

            # If not, see if it's a file. Allow OS filesystem errors to raise.
            with open(image, "rb") as f:
                data = f.read()

        # Assume input in bytes.
        else:
            data = image

        (data, mimetype) = _normalize_to_bytes(data, width, format)
        this_file = media_file_manager.add(data, mimetype=mimetype)
        proto_img.url = this_file.url
示例#3
0
def image_to_url(image,
                 width,
                 clamp,
                 channels,
                 format,
                 image_id,
                 allow_emoji=False):
    # PIL Images
    if isinstance(image, ImageFile.ImageFile) or isinstance(
            image, Image.Image):
        data = _PIL_to_bytes(image, format)

    # BytesIO
    elif type(image) is io.BytesIO:
        data = _BytesIO_to_bytes(image)

    # Numpy Arrays (ie opencv)
    elif type(image) is np.ndarray:
        data = _verify_np_shape(image)
        data = _clip_image(data, clamp)

        if channels == "BGR":
            if len(data.shape) == 3:
                data = data[:, :, [2, 1, 0]]
            else:
                raise StreamlitAPIException(
                    'When using `channels="BGR"`, the input image should '
                    "have exactly 3 color channels")

        data = _np_array_to_bytes(data, format=format)

    # Strings
    elif isinstance(image, str):
        # If it's a url, then set the protobuf and continue
        try:
            p = urlparse(image)
            if p.scheme:
                return image
        except UnicodeDecodeError:
            pass

        # If not, see if it's a file.
        try:
            with open(image, "rb") as f:
                data = f.read()
        except:
            if allow_emoji:
                # This might be an emoji string, so just pass it to the frontend
                return image
            else:
                # Allow OS filesystem errors to raise
                raise

    # Assume input in bytes.
    else:
        data = image

    (data, mimetype) = _normalize_to_bytes(data, width, format)

    this_file = media_file_manager.add(data, mimetype, image_id)
    return this_file.url