Nothing
#'@title Crop Image
#'
#'@description Crops an image (or matrix) either by specifying axis-aligned limits
#'(`width_limits`/`height_limits`) or by specifying a centered box size via `center`.
#'
#'@param image Default `NULL`. 3-layer RGB/4-layer RGBA array, `rayimg` class, or filename of an image.
#'@param width_limits Default `NULL`. Length-2 numeric `(xmin, xmax)` along the width (x/columns).
#' Values in 0..1 are treated as fractions of image width; otherwise they are pixel indices.
#' Mutually exclusive with `center`. If provided alone, `height_limits` defaults to full height.
#'@param height_limits Default `NULL`. Length-2 numeric `(ymin, ymax)` along the height (y/rows).
#' Values in 0..1 are treated as fractions of image height; otherwise they are pixel indices.
#' Mutually exclusive with `center`. If provided alone, `width_limits` defaults to full width.
#'@param center Default `NULL`. Length-2 numeric `(height, width)` for a center-crop.
#' Values in (0,1] are treated as fractions of `(image height, image width)`; otherwise pixels.
#' Mutually exclusive with `width_limits`/`height_limits`.
#'@param filename Default `NULL`. The filename of the image to be saved. If this is not given, the image will be plotted instead.
#'@param preview Default `FALSE`. Whether to plot the cropped image, or just to return the values.
#'@return A `rayimg` array with the cropped region.
#'@export
#'@examplesIf interactive() || identical(Sys.getenv("IN_PKGDOWN"), "true")
#'# Left half of the image
#'render_crop(dragon,
#' width_limits = c(0, 0.50),
#' height_limits = c(0, 1)) |>
#' plot_image()
#'# Right half of the image
#'render_crop(dragon,
#' width_limits = c(0.50, 1),
#' height_limits = c(0, 1)) |>
#' plot_image()
#'# Top middle of the image (25%–50% height, 25%–75% width)
#'render_crop(dragon,
#' height_limits = c(0.25, 0.50),
#' width_limits = c(0.25, 0.75)) |>
#' plot_image()
#'# Top middle, explicit pixel coords (for a 200x200 image)
#'render_crop(dragon,
#' height_limits = c(50, 100),
#' width_limits = c(50, 150)) |>
#' plot_image()
#'# Center-crop: 50% height and width of the image
#'render_crop(dragon, center = c(0.5, 0.5)) |>
#' plot_image()
#'# Center-crop: fixed 50x100 pixels
#'render_crop(dragon, center = c(50, 100)) |>
#' plot_image()
render_crop = function(
image = NULL,
width_limits = NULL,
height_limits = NULL,
center = NULL,
filename = NULL,
preview = FALSE
) {
if (is.null(image)) {
stop("`image` must be provided.", call. = FALSE)
}
use_limits = !is.null(width_limits) || !is.null(height_limits)
use_center = !is.null(center)
if (use_limits && use_center) {
stop(
"Provide either `width_limits`/`height_limits` OR `center`, not both.",
call. = FALSE
)
}
if (!use_limits && !use_center) {
stop(
"You must provide `width_limits`/`height_limits`, or `center`.",
call. = FALSE
)
}
if (!is.null(filename)) {
if (tools::file_ext(filename) != "png") {
filename = paste0(filename, ".png")
}
}
# Normalize input and preserve metadata
temp_image = ray_read_image(image)
imagetype = attr(temp_image, "filetype")
img_source_linear = attr(temp_image, "source_linear")
colorspace = attr(temp_image, "colorspace")
white_current = attr(temp_image, "white_current")
h = nrow(temp_image)
w = ncol(temp_image)
to_px_range = function(lims, len) {
if (length(lims) != 2 || !is.numeric(lims)) {
stop("Limits must be length-2 numeric.", call. = FALSE)
}
a = lims[1]
b = lims[2]
if (all(a >= 0, a <= 1, b >= 0, b <= 1)) {
start = floor(min(a, b) * len) + 1L
end = ceiling(max(a, b) * len)
} else {
start = floor(min(a, b))
end = ceiling(max(a, b))
}
start = max(1L, start)
end = min(len, end)
if (end < start) {
stop(
"Computed limits are empty after clamping; check your inputs.",
call. = FALSE
)
}
c(start, end)
}
if (use_limits) {
if (is.null(width_limits)) {
width_limits = c(0, 1)
}
if (is.null(height_limits)) {
height_limits = c(0, 1)
}
x_rng = to_px_range(width_limits, w)
y_rng = to_px_range(height_limits, h)
x_start = x_rng[1]
x_end = x_rng[2]
y_start = y_rng[1]
y_end = y_rng[2]
} else {
if (length(center) != 2 || !is.numeric(center)) {
stop(
"`center` must be a length-2 numeric vector (height, width).",
call. = FALSE
)
}
box_h = center[1]
box_w = center[2]
box_h = if (box_h > 0 && box_h <= 1) {
round(max(1, box_h * h))
} else {
round(box_h)
}
box_w = if (box_w > 0 && box_w <= 1) {
round(max(1, box_w * w))
} else {
round(box_w)
}
box_h = min(max(1L, box_h), h)
box_w = min(max(1L, box_w), w)
y_start = floor((h - box_h) / 2) + 1L
y_end = y_start + box_h - 1L
x_start = floor((w - box_w) / 2) + 1L
x_end = x_start + box_w - 1L
}
if (imagetype != "matrix") {
temp_image = temp_image[y_start:y_end, x_start:x_end, , drop = FALSE]
} else {
temp_image = temp_image[y_start:y_end, x_start:x_end, drop = FALSE]
}
temp_image = ray_read_image(
temp_image,
filetype = imagetype,
source_linear = img_source_linear,
assume_colorspace = colorspace,
assume_white = white_current
)
handle_image_output(temp_image, filename = filename, preview = preview)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.