Example #1
0
def test_max_dpr():
    request = {"width": 500, "height": 500, "dpr": 3}
    original = {"width": 1920, "height": 1080}
    max_dpr = 2
    result = plan_scale(request, original, max_dpr)
    assert result["width"] == 1000
    assert result["height"] == 563
Example #2
0
def test_wide_tall_crop_unspecified_upscale():
    request = {"width": 5400, "height": 9600, "mode": "crop"}
    original = {"width": 1920, "height": 1080}
    result = plan_scale(request, original)
    assert result["width"] == 608
    assert result["height"] == 1080
    assert result["crop"] == "656,0,1263,1079"
Example #3
0
def test_wide_tall_crop_middle_upscale():
    request = {"width": 5400, "height": 9600, "center-x": 0.5, "center-y": 0.5}
    original = {"width": 1920, "height": 1080}
    result = plan_scale(request, original)
    assert result["width"] == 608
    assert result["height"] == 1080
    assert result["crop"] == "656,0,1263,1079"
Example #4
0
def test_tall_wide_crop_middle_downscale():
    request = {"width": 960, "height": 540, "center-x": 0.5, "center-y": 0.5}
    original = {"width": 1080, "height": 1920}
    result = plan_scale(request, original)
    assert result["width"] == 960
    assert result["height"] == 540
    assert result["crop"] == "0,656,1079,1263"
Example #5
0
def test_wide_square_crop_right_upscale():
    request = {"width": 2000, "height": 2000, "center-x": 0.9, "center-y": 0.5}
    original = {"width": 1920, "height": 1080}
    result = plan_scale(request, original)
    assert result["width"] == 1080
    assert result["height"] == 1080
    assert result["crop"] == "840,0,1919,1079"
Example #6
0
def test_wide_square_crop_left_downscale():
    request = {"width": 200, "height": 200, "center-x": 0.1, "center-y": 0.5}
    original = {"width": 1920, "height": 1080}
    result = plan_scale(request, original)
    assert result["width"] == 200
    assert result["height"] == 200
    assert result["crop"] == "0,0,1079,1079"
Example #7
0
async def planner(request: Request):
    """Redirect to a canonical url based on the request and the original image dimensions."""

    tenant = request.path_params["tenant"]
    image_uri = request.path_params["image_uri"]
    config: Config = request.app.state.config

    span = Hub.current.scope.span
    if span is not None:
        span.set_tag("tenant", tenant)

    in_q, fwd_q = extract_forwardable_params(dict(request.query_params))
    try:
        q = query_schema.validate(in_q)
    except Exception:
        log.warning("invalid query parameters (planner) in request %s", request.url)
        raise HTTPException(400, "invalid set of query parameters")

    # size is a shortcut to set width/height to the same size and force fit mode
    box_size = q.pop("size", 0)
    if box_size > 0:
        q["width"] = q["height"] = box_size
        q["mode"] = "fit"

    # If width or height are set but zero, behave as if they weren't specified
    if "width" in q and q["width"] == 0:
        del q["width"]
    if "height" in q and q["height"] == 0:
        del q["height"]

    if ("center-x" in q and "center-y" not in q) or (
        "center-y" in q and "center-x" not in q
    ):
        raise HTTPException(400, "both center-x and center-y required")

    if "center-x" in q and ("width" not in q or "height" not in q):
        raise HTTPException(400, "both width and height are required when cropping")

    imageinfo_url = cache_url(
        config.cache_endpoint(),
        config.app_path_prefixes(),
        "imageinfo",
        tenant,
        image_uri,
        fwd_q,
    )
    r = await make_request(request, imageinfo_url)
    output_headers = cache_headers_with_config(config, tenant, r)

    if r.status_code == 304:
        return Response(status_code=304, headers=output_headers)

    imageinfo = r.json()

    if (
        "mode" in q
        and (q["mode"] == "crop" and "center-x" not in q)
        and config.visionrecognizer_url() is not None
    ):
        # Crop requested but center point not specified. Perform feature detection.
        visionrecognizer_url = cache_url(
            config.cache_endpoint(),
            config.app_path_prefixes(),
            "visionrecognizer",
            tenant,
            image_uri,
            fwd_q,
        )
        try:
            r = await make_request(request, visionrecognizer_url)
            if r.status_code == 304:
                return Response(status_code=304, headers=output_headers)
            visionrecognizer_result = r.json()
            q["center-x"] = visionrecognizer_result["centerPoint"]["x"]
            q["center-y"] = (
                1.0 - visionrecognizer_result["centerPoint"]["y"]
            )  # visionrecognizer has a flipped y-axis
        except Exception:
            # the downstream code defaults to center crop
            pass

    scale_params = plan_scale(q, imageinfo, config.max_pixel_ratio(tenant))
    size_identical = (
        scale_params["width"] == imageinfo["width"]
        and scale_params["height"] == imageinfo["height"]
    )

    if "quality" in q:
        scale_params["quality"] = q["quality"]
    else:
        scale_params["quality"] = config.default_quality(tenant)

    default_format = config.default_format(tenant)
    if "format" in q:
        scale_params["format"] = q["format"]
    elif default_format and not size_identical:
        # Convert to default format if scaling, otherwise
        # allow grabbing the original size & format.
        scale_params["format"] = default_format
    else:
        scale_params["format"] = imageinfo["format"]

    if (
        (
            size_identical
            and scale_params["format"] == imageinfo["format"]
            and "quality" not in q
        )
        or (
            imageinfo["format"] == "gif" and scale_params["format"] == "gif"
        )  # We don't process GIFs or PNGs unless format conversion is explicitly requested
        or (imageinfo["format"] == "png" and scale_params["format"] == "png")
    ):
        # The request is best served by the original image, so redirect straight to that.
        original_url = cache_url(
            None,  # Get relative URL for redirect
            config.app_path_prefixes(),
            "original",
            tenant,
            image_uri,
            fwd_q,
        )
        log.debug(
            "redirecting to original request %s with input path %s",
            original_url,
            request.url.path,
        )
        return RedirectResponse(original_url, headers=output_headers)

    scale_params.update(fwd_q)
    scale_url = cache_url(
        None,  # Get relative URL for redirect
        config.app_path_prefixes(),
        "scale",
        tenant,
        image_uri,
        scale_params,
    )
    log.debug(
        "redirecting to scale request %s with input path %s",
        scale_url,
        request.url.path,
    )
    return RedirectResponse(scale_url, headers=output_headers)
Example #8
0
def test_dpr():
    request = {"width": 500, "height": 500, "dpr": 3}
    original = {"width": 1920, "height": 1080}
    result = plan_scale(request, original)
    assert result["width"] == 1500
    assert result["height"] == 844
Example #9
0
def test_tall_square_upscale():
    request = {"width": 4000, "height": 4000}
    original = {"width": 1080, "height": 1920}
    result = plan_scale(request, original)
    assert result["width"] == 1080
    assert result["height"] == 1920
Example #10
0
def test_wide_square_downscale():
    request = {"width": 400, "height": 400}
    original = {"width": 1920, "height": 1080}
    result = plan_scale(request, original)
    assert result["width"] == 400
    assert result["height"] == 225
Example #11
0
def test_square_tall_upscale():
    request = {"width": 500, "height": 1500}
    original = {"width": 200, "height": 200}
    result = plan_scale(request, original)
    assert result["width"] == 200
    assert result["height"] == 200
Example #12
0
def test_square_linear_downscale():
    request = {"width": 200, "height": 200}
    original = {"width": 1000, "height": 1000}
    result = plan_scale(request, original)
    assert result["width"] == 200
    assert result["height"] == 200
Example #13
0
def test_tall_square_stretch_downscale():
    request = {"width": 400, "height": 400, "mode": "stretch"}
    original = {"width": 1080, "height": 1920}
    result = plan_scale(request, original)
    assert result["width"] == 400
    assert result["height"] == 400