├── .Rbuildignore
├── .gitignore
├── DESCRIPTION
├── LICENSE
├── LICENSE.md
├── NAMESPACE
├── NEWS.md
├── R
├── eyedropper.R
├── generate-palette.R
├── helpers.R
└── pencil-case.R
├── README.Rmd
├── README.md
├── cran-comments.md
├── dev
├── images
│ ├── belize-output-12.png
│ ├── belize-output-s.png
│ ├── belize-s.jpg
│ ├── belize-swatch.png
│ ├── belize.jpg
│ ├── calibrate.png
│ ├── cat4.png
│ ├── catedral-s.png
│ ├── eyedropper.gif
│ ├── eyedropper1.jpg
│ ├── feature.png.png
│ ├── hex-amatic.png
│ ├── misc
│ │ └── graffiti.png
│ ├── mountains-in-autumn.png
│ ├── mountains-selector.png
│ ├── mountains.png
│ ├── pencil-case
│ │ ├── mastodon-blood-mountain.png
│ │ ├── mastodon-crack-the-skye.png
│ │ ├── mastodon-empoeror-of-sands.png
│ │ ├── mastodon-hushed-and-grim.png
│ │ ├── mastodon-leviathan.png
│ │ ├── mastodon-once-more-around-the-sun.png
│ │ ├── mastodon-remission.png
│ │ ├── mastodon-the-hunter.png
│ │ ├── motley-crue.png
│ │ ├── mountains-in-autumn.png
│ │ ├── tool-10000-days.png
│ │ ├── tool-fear-inoculum.png
│ │ └── tool-lateralus.png
│ ├── show-pencil-case.png
│ ├── snes
│ │ ├── mana.png
│ │ ├── secret-of-mana-40p.png
│ │ ├── secret-of-mana-80p.png
│ │ ├── secret-of-mana-og.png
│ │ └── secret-of-mana.png
│ ├── sunset-sampler-s.png
│ ├── sunset-sampler.png
│ ├── sunset-south-coast-output-s.png
│ ├── sunset-south-coast-output.png
│ ├── sunset-south-coast-s.jpg
│ └── sunset-south-coast.jpg
├── scripts
│ ├── dev.R
│ ├── hex.R
│ ├── show-pal.R
│ ├── tests.R
│ └── tsp.R
└── tests
│ └── tests.R
├── eyedroppeR.Rproj
├── inst
└── images
│ ├── calibration.png
│ ├── hex.png
│ └── sunset.png
└── man
├── choose_font_colour.Rd
├── extract_pal.Rd
├── eyedropper.Rd
├── generate_palette.Rd
├── make_output.Rd
├── min_max.Rd
├── modify_saturation.Rd
├── palette.Rd
├── paste_pal_code.Rd
├── pencil_case.Rd
├── show_pal.Rd
├── show_pencil_case.Rd
├── sort_pal.Rd
├── sort_pal_auto.Rd
└── swatch.Rd
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^.*\.Rproj$
2 | ^\.Rproj\.user$
3 | README.Rmd
4 | README.md
5 | README_files
6 | ^cran-comments\.md$
7 | ^CRAN-SUBMISSION$
8 | LICENSE.md
9 | dev
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .Rproj.user
2 | .Rhistory
3 | .RData
4 | .Ruserdata
5 | dev/images/too-big
6 | dev/images/pencil-case/
7 | dev/images/albums/
8 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: eyedroppeR
2 | Type: Package
3 | Title: Extract Hex Codes by Clicking an Image
4 | Version: 0.3.0
5 | Authors@R:
6 | c(person(given = "Daniel",
7 | family = "Oehm",
8 | role = c("aut", "cre"),
9 | email = "danieloehm@gmail.com"))
10 | Description: Plots an image either locally or from a URL and allows the user
11 | to click the image to save the hex of the pixel. User can select multiple
12 | colours or automatically select a user specified number of colours.
13 | Depends:
14 | R (>= 3.5.0)
15 | Imports:
16 | ggplot2,
17 | purrr,
18 | grid,
19 | glue,
20 | ggpath,
21 | magick,
22 | stringr,
23 | gridExtra,
24 | crayon,
25 | snakecase,
26 | ggtext,
27 | TSP,
28 | tidyr,
29 | gt,
30 | openai,
31 | dplyr
32 | License: MIT + file LICENSE
33 | URL: https://github.com/doehm/eyedroppeR
34 | BugReports: https://github.com/doehm/eyedroppeR/issues
35 | Encoding: UTF-8
36 | LazyData: true
37 | RoxygenNote: 7.2.3
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | YEAR: 2022
2 | COPYRIGHT HOLDER: Daniel Oehm
3 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | ## MIT License
2 |
3 | Copyright (c) 2022 Daniel Oehm
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | # Generated by roxygen2: do not edit by hand
2 |
3 | export(extract_pal)
4 | export(eyedropper)
5 | export(generate_palette)
6 | export(modify_saturation)
7 | export(palette)
8 | export(pencil_case)
9 | export(show_pal)
10 | export(show_pencil_case)
11 | export(sort_pal)
12 | export(sort_pal_auto)
13 | export(swatch)
14 | import(dplyr)
15 | import(ggplot2)
16 | importFrom(TSP,as.TSP)
17 | importFrom(TSP,solve_TSP)
18 | importFrom(crayon,cyan)
19 | importFrom(crayon,white)
20 | importFrom(ggpath,geom_from_path)
21 | importFrom(ggplot2,ggsave)
22 | importFrom(ggtext,geom_richtext)
23 | importFrom(glue,glue)
24 | importFrom(grDevices,col2rgb)
25 | importFrom(grDevices,hsv)
26 | importFrom(grDevices,rgb2hsv)
27 | importFrom(grid,grid.locator)
28 | importFrom(gridExtra,grid.arrange)
29 | importFrom(gt,cell_text)
30 | importFrom(gt,cells_body)
31 | importFrom(gt,cols_hide)
32 | importFrom(gt,cols_width)
33 | importFrom(gt,default_fonts)
34 | importFrom(gt,google_font)
35 | importFrom(gt,gt)
36 | importFrom(gt,px)
37 | importFrom(gt,tab_header)
38 | importFrom(gt,tab_options)
39 | importFrom(gt,tab_style)
40 | importFrom(gt,text_transform)
41 | importFrom(magick,image_append)
42 | importFrom(magick,image_data)
43 | importFrom(magick,image_info)
44 | importFrom(magick,image_read)
45 | importFrom(magick,image_resize)
46 | importFrom(magick,image_scale)
47 | importFrom(magick,image_write)
48 | importFrom(openai,create_image)
49 | importFrom(purrr,map_chr)
50 | importFrom(purrr,map_dbl)
51 | importFrom(purrr,map_dfr)
52 | importFrom(purrr,reduce)
53 | importFrom(snakecase,to_snake_case)
54 | importFrom(stats,dist)
55 | importFrom(stats,kmeans)
56 | importFrom(stringr,str_detect)
57 | importFrom(stringr,str_length)
58 | importFrom(stringr,str_remove)
59 | importFrom(stringr,str_remove_all)
60 | importFrom(stringr,str_split)
61 | importFrom(tidyr,everything)
62 | importFrom(tidyr,pivot_wider)
63 |
--------------------------------------------------------------------------------
/NEWS.md:
--------------------------------------------------------------------------------
1 | # eyedroppeR 0.1.0
2 |
3 | * New release
4 | * Added a `NEWS.md` file to track changes to the package.
5 |
--------------------------------------------------------------------------------
/R/eyedropper.R:
--------------------------------------------------------------------------------
1 | utils::globalVariables(c("x", "y", "id", "bg", "name", "text"))
2 |
3 | #' Eyedropper
4 | #'
5 | #' Plots an image and allows the user to click on the image to
6 | #' return the hex of the pixel. Can select multiple colours at
7 | #' once by setting \code{n}.
8 | #'
9 | #' @param n Number of colours to extract from the image
10 | #' @param img_path Path to image. Can be local or from a URL. If left \code{NULL},
11 | #' \code{eyedropper} will read the image address directly from the clipboard.
12 | #' @param label Label for the palette.
13 | #' @param inc_palette Logical. If \code{TRUE} it will automatically extract a palette
14 | #' first and then you can select the desired colours.
15 | #' @param n_swatches Number of swatches to extract from the image prior to selecting colours.
16 | #' @param print_output Print output to console to easily copy and paste into your script.
17 | #' @param calibrate Set to `TRUE` to calibrate the plot coordinates. Given the monitor
18 | #' resolution, scaling, etc it can throw off the pixel selection. Runs but default the first
19 | #' time the function is used.
20 | #' @param swatch_radius Radius of the image for the swatch. Default 50 to make it a circle. Use 5 for rounded edges.
21 | #' @param pixelate If `TRUE` or some numeric value, a low-res image will be displayed so that it is easier to select the right colour. Pixelate
22 | #' is set to `40` pixels. To make it more pixelated use a lower number of pixels e.g. `pixelate = 40`. If
23 | #' pixelate is used the palette selector at the bottom of the image won't be shown.
24 | #'
25 | #' @details Use \code{eyedropper} with the following steps:
26 | #' \enumerate{
27 | #' \item{Find the image you want to pick colours from online.}
28 | #' \item{Right-click and 'copy image address'.}
29 | #' \item{Choose how many colours to pick e.g. \code{n = 5}.}
30 | #' \item{Run \code{pal <- eyedropper(n = 5, img_path = 'paste-image-path-here')}.}
31 | #' \item{Click 5 areas of the image. Thes image will be stretched to the borders of the window, but that's OK.}
32 | #' \item{Done! Copy the returned string / message and add it to you script and start using \code{pal}}
33 | #' }
34 | #'
35 | #' The first time the function is run it will initiate a calibration set. This is so the `y` coordinates are
36 | #' scaled properly as this can depend on the monitors resolution, scaling, etc. In only takes a couple of seconds
37 | #' and you only have to do it once.
38 | #'
39 | #' Make sure you click as near as practicable to the top and bottom of the border of the windew within the dot.
40 | #'
41 | #' @return A character vector of hex codes
42 | #' @export
43 | #'
44 | #' @import ggplot2
45 | #' @importFrom magick image_read image_data image_write image_info image_resize image_append image_scale
46 | #' @importFrom purrr map_chr map_dbl reduce
47 | #' @importFrom grid grid.locator
48 | #' @importFrom glue glue
49 | #' @importFrom ggpath geom_from_path
50 | #' @importFrom stringr str_remove str_split
51 | #' @importFrom stats kmeans dist
52 | #' @importFrom gridExtra grid.arrange
53 | #' @importFrom crayon white cyan
54 | #' @importFrom snakecase to_snake_case
55 | #' @importFrom TSP as.TSP solve_TSP
56 | #' @importFrom ggtext geom_richtext
57 | #' @importFrom grDevices col2rgb
58 | #' @importFrom ggplot2 ggsave
59 | #'
60 | #' @examples \dontrun{
61 | #'
62 | #' path <- file.path(system.file(package = "eyedroppeR"), "images", "hex.png")
63 | #'
64 | #' # Run eyedropper and click on 4 colours
65 | #' pal <- eyedropper(n = 4, path)
66 | #'
67 | #' pal
68 | #'
69 | #' }
70 | eyedropper <- function(
71 | n,
72 | img_path = NULL,
73 | label = NULL,
74 | inc_palette = TRUE,
75 | n_swatches = 24,
76 | print_output = TRUE,
77 | calibrate = FALSE,
78 | swatch_radius = 50,
79 | pixelate = FALSE
80 | ) {
81 |
82 | # name palette
83 | # keeping this here in case I add back in the parameter
84 | if(is.null(label)) label <- "pal"
85 |
86 | # calibrate
87 | if(calibrate | !exists("eyedropper_calibration", mode = "environment")) {
88 | plt_calibrate <- tibble(
89 | x = 0.5,
90 | y = c(0.9, 0.1),
91 | text = c("To calibrate,\nfirst click here\nwithin the dot", "Then click here\nwithin the dot")
92 | ) %>%
93 | ggplot() +
94 | annotation_raster(image_read(file.path(system.file(package = "eyedroppeR"), "images", "calibration.png")), xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf) +
95 | geom_text(aes(x-0.1, y, label = text), size = 8, hjust = 1, lineheight = 0.8) +
96 | ylim(0, 1) +
97 | xlim(0, 1) +
98 | theme_void()
99 | print(plt_calibrate)
100 |
101 | calibration_points <- list()
102 | lab <- c("Top", "Bottom")
103 | for(k in 1:2) {
104 | cat(lab[k])
105 | calibration_points[[k]] <- grid.locator(unit = "npc")
106 | cat(" ✔\n")
107 | }
108 | cat("-- Calibration done --\n")
109 |
110 | # create a new environment to store the calibration points
111 | eyedropper_calibration <<- new.env()
112 |
113 | # calculate min and max y
114 | eyedropper_calibration$max_y <- as.numeric(calibration_points[[1]]$y)
115 | eyedropper_calibration$min_y <- as.numeric(calibration_points[[2]]$y)
116 |
117 | }
118 |
119 | # if no image is given use the standard
120 | img_shadow <- TRUE
121 | if(is.null(img_path)) {
122 | img_path <- file.path(system.file(package = "eyedroppeR"), "images", "hex.png")
123 | img_shadow <- FALSE
124 | }
125 |
126 | err_bad_link <- simpleError("Incorrect path. Please supply the correct link to img_path")
127 | tryCatch(
128 | {
129 | # include palette?
130 | if(inc_palette) {
131 | ex_pal <- suppressMessages(extract_pal(n_swatches, img_path, plot_output = FALSE, save_output = TRUE))
132 | img <- image_read(img_path)
133 | } else {
134 | img <- image_read(img_path)
135 | }
136 | },
137 | error = function(e) stop(err_bad_link)
138 | )
139 |
140 | # resize and write image
141 | info <- image_info(img)
142 | ht <- min(info$height, 800)
143 | wd <- info$width*ht/info$height
144 | img_rs <- image_resize(img, geometry = paste0(ht, "x", wd))
145 | temp <- tempfile()
146 | image_write(img_rs, path = temp)
147 |
148 | # plot image with extracted palette
149 | temp_selector <- tempfile(fileext = ".png")
150 | ggsave(plot = show_pal(ex_pal$pal), filename = temp_selector, height = ht/10, width = wd, units = "px")
151 | img_selector <- image_append(image_scale(c(img_rs, image_read(temp_selector)), as.character(ht)), stack = TRUE)
152 |
153 | # pixelate
154 | if(pixelate | is.numeric(pixelate)) {
155 | if(is.numeric(pixelate)) {
156 | geo <- glue("{pixelate}x")
157 | } else {
158 | geo <- "40x"
159 | }
160 | img_selector <- image_resize(img, geometry = geo, filter = "Point")
161 | }
162 |
163 | # plot image for clicking
164 | print(ggplot() +
165 | annotation_raster(img_selector, xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf))
166 |
167 | # pick colours
168 | eye_ls <- list()
169 | message(white("\nClick on image to select colours\n"))
170 | for(k in 1:n) {
171 | cat(glue("Colours selected: {k-1}/{n}\r"))
172 | eye_ls[[k]] <- grid.locator(unit = "npc")
173 | if(info$width*as.numeric(eye_ls[[k]]$x) < 0) stop("...eyedropper killed\n")
174 | }
175 | cat(glue("Colours selected: {n}/{n}\n\n"))
176 |
177 | # get image data and extract from image
178 | img_dat <- image_data(img_selector)
179 | dims <- dim(img_dat)
180 |
181 | pal <- map_chr(eye_ls, ~{
182 | coords <- as.numeric(str_remove(reduce(.x, c), "npc"))
183 | coords[2] <- 1-min_max(coords[2], 0, 1, a0 = eyedropper_calibration$min_y, b0 = eyedropper_calibration$max_y)
184 | xpx <- ceiling(coords[1]*dims[2])
185 | ypx <- ceiling(coords[2]*dims[3])
186 | paste0("#", paste0(img_dat[, xpx, ypx][1:3], collapse = ""))
187 | })
188 |
189 | # print pal to copy + paste
190 | if(print_output) paste_pal_code(pal, label)
191 |
192 | # make plot output
193 | if(label == "pal") label <- NULL
194 | print(swatch(pal, img = img_path, label = label, img_shadow = img_shadow, radius = swatch_radius))
195 |
196 | # return
197 | list(
198 | pal = pal,
199 | img_path = img_path
200 | )
201 |
202 | }
203 |
204 |
205 | #' Extracts palette from an image
206 | #'
207 | #' The image is read in using \code{magick}, converted to RGB and clustered using kmeans. The user
208 | #' must specify the number of clusters. The cluster centroids become the palette values.
209 | #' The function will ask the user to sort the palette values after clustering
210 | #'
211 | #' @param n Number of colours to extract
212 | #' @param img_path Path to image. If `NULL` the function will read from the clipboard
213 | #' @param label Label for the palette.
214 | #' @param sort Sort method. Either 'manual' or 'auto'
215 | #' @param plot_output logical. Default \code{TRUE}. Plots the output of the extracted palette.
216 | #' @param save_output logical. Default \code{FALSE}. Save the output of the extracted palette.
217 | #' @param print_output Print output to console to easily copy and paste into your script.
218 | #' @param swatch_radius Radius of the image for the swatch. Default 50 to make it a circle. Use 5 for rounded edges.
219 | #'
220 | #' @return Returns a character vector of hex codes
221 | #' @export
222 | #'
223 | #' @examples
224 | #' path <- file.path(system.file(package = "eyedroppeR"), "images", "sunset.png")
225 | #'
226 | #' \dontrun{
227 | #' extract_pal(8, path)
228 | #' }
229 | extract_pal <- function(
230 | n,
231 | img_path,
232 | label = NULL,
233 | sort = "auto",
234 | plot_output = TRUE,
235 | save_output = FALSE,
236 | print_output = TRUE,
237 | swatch_radius = 50
238 | ) {
239 |
240 | err_bad_link <- simpleError("Incorrect path. Please supply the correct link to img_path")
241 | tryCatch(
242 | {
243 | img <- image_read(img_path)
244 | },
245 | error = function(e) stop(err_bad_link)
246 | )
247 |
248 | # name palette
249 | if(is.null(label)) label <- "pal"
250 |
251 | # resize and write image
252 | info <- image_info(img)
253 | ht <- min(info$height, 600)
254 | wd <- info$width*ht/info$height
255 | img_rs <- image_resize(img, geometry = paste0(ht, "x", wd))
256 | temp <- tempfile()
257 | image_write(img_rs, path = temp)
258 |
259 | # setting array for clustering
260 | x <- as.integer(as.array(image_data(img_rs, "rgb")))
261 | rgb_mat <- unique(apply(x, 3, "c"))
262 |
263 | # kmeans
264 | km <- kmeans(rgb_mat, n)
265 | km <- round(km$centers)
266 |
267 | # pal from centers
268 | pal <- map_chr(1:n, ~rgb(km[.x,1], km[.x,2], km[.x,3], maxColorValue = 255))
269 |
270 | # sort
271 | pal <- sort_pal_auto(pal, label)
272 | if(sort == "manual") {
273 | print(show_pal(pal))
274 | nx <- as.numeric(readline("How many colours to pick? "))
275 | pal <- sort_pal(pal, n = nx)
276 | }
277 |
278 | # print pal
279 | if(print_output) paste_pal_code(pal, label)
280 |
281 | # make plot output
282 | temp_final <- NULL
283 | if(label == "pal") label <- NULL
284 | if(plot_output) print(swatch(pal, temp, label = label, radius = swatch_radius))
285 |
286 | # return
287 | list(
288 | pal = pal,
289 | img_path = temp
290 | )
291 |
292 | }
293 |
294 |
295 |
--------------------------------------------------------------------------------
/R/generate-palette.R:
--------------------------------------------------------------------------------
1 |
2 | #' Generate palette
3 | #'
4 | #' ⚠️ DEPRECATED: openai has been archived and I have to work out how to generate
5 | #' images with {ellmer} and the new APIs.
6 | #'
7 | #' @param n Number of colours in the palette
8 | #' @param prompt Prompt
9 | #'
10 | #' @importFrom openai create_image
11 | #' @importFrom stringr str_length
12 | #'
13 | #' @return A vector of hex codes
14 | #' @export
15 | #'
16 | #' @examples
17 | #' # x <- generate_palette(4, 'a trail in a dense rainforest')
18 | generate_palette <- function(n, prompt) {
19 | x <- create_image(prompt)
20 | d <- extract_pal(n, x$data$url, plot_output = FALSE, save_output = TRUE)
21 | print(swatch(d$pal, d$img_path, padding = 1))
22 | list(
23 | pal = d$pal,
24 | eyedropper = d,
25 | img = x$data$url
26 | )
27 | }
28 |
--------------------------------------------------------------------------------
/R/helpers.R:
--------------------------------------------------------------------------------
1 | #' Show palette
2 | #'
3 | #' Plots the supplied palette for quick inspection
4 | #'
5 | #' @param pal Palette. Vector of hex codes
6 | #'
7 | #' @return ggplot
8 | #' @export
9 | #'
10 | #' @examples
11 | #' pal <- c('#57364e', '#566f1b', '#97a258', '#cac58b', '#dbedd5')
12 | #' show_pal(pal)
13 | show_pal <- function(pal) {
14 | ggplot(data.frame(x = 1:length(pal),y = 1)) +
15 | geom_col(aes(x, y), fill = pal, width = 1) +
16 | theme_void() +
17 | theme(
18 | plot.margin = margin(l=-12,r=-12,t=-20,b=-20)
19 | )
20 | }
21 |
22 | #' Swatch of colour palette
23 | #'
24 | #' @param pal Vector of colours
25 | #' @param img Image address. Either local file or URL
26 | #' @param label Label for the palette.
27 | #' @param padding To add whitespace to the top of image
28 | #' @param radius The radius of the feature image. Choose 50 for a circle, less then 50 for rounded square/rectangle.
29 | #' @param ncols Number of cols in a row
30 | #' @param img_shadow Logical. Apply a shadow to the feature image output.
31 | #' @param shape Either 'original' for the original image dimensions or "square"
32 | #' to crop to square with rounded corners. A high enough radius will turn the square to a circle.
33 | #'
34 | #' @return html doc
35 | #' @export
36 | #'
37 | #' @importFrom gt gt tab_style tab_header tab_options cells_body google_font cell_text default_fonts text_transform px
38 | #' @importFrom tidyr pivot_wider everything
39 | #' @importFrom stringr str_remove_all str_detect
40 | #' @import dplyr
41 | #'
42 | #' @examples
43 | #' url <- "https://github.com/doehm/eyedroppeR/raw/main/dev/images/sunset-south-coast.jpg"
44 | #' x <- extract_pal(4, url)
45 | #' swatch(x$pal, url)
46 | swatch <- function(
47 | pal,
48 | img = NULL,
49 | label = NULL,
50 | padding = 0,
51 | radius = 20,
52 | ncols = 8,
53 | img_shadow = TRUE,
54 | shape = "original"
55 | ) {
56 |
57 | # set the number of cols for the swatch
58 | if(length(pal) > ncols & length(pal) < 2*ncols) {
59 | ncols <- ceiling(length(pal)/2)
60 | } else {
61 | ncols <- min(ncols, length(pal))
62 | }
63 |
64 | padding <- paste0(rep("
", padding), collapse = "")
65 | nrows <- ceiling(length(pal)/ncols)
66 |
67 | # radius on x and y for the rounded corners of the image
68 | rx <- radius
69 | ry <- radius
70 |
71 | # css and function for the main image
72 | img_style <- glue("border-radius: {rx}px {ry}px; box-shadow: 0 0 10px 2px rgba(0,0,0,{0.3*img_shadow}); object-fit: cover;")
73 | img_header <- function(tbl) {
74 | if(is.null(img)) {
75 | out <- tbl
76 | } else {
77 | if(shape == "original") {
78 | info <- image_read(img) |>
79 | image_info()
80 | wd <- info$width/info$height*300
81 | } else {
82 | wd <- 300
83 | }
84 | out <- tbl |>
85 | tab_header(
86 | title = gt::html(glue("{padding}
")),
87 | subtitle = gt::html(glue("{label}"))
88 | )
89 | }
90 | }
91 |
92 | # function and css for the colour dots
93 | dot_ <- function(bg, circle) {
94 |
95 | txt <- choose_font_colour(bg)
96 |
97 | str_remove_all(glue("height: 150px;
98 | width: 150px;
99 | background-color: {bg};
100 | color: {txt};
101 | font-weight: 400;
102 | font-size: 12px;
103 | border-radius: 50%;
104 | display: inline-block;
105 | box-shadow: 0 0 10px 2px rgba(0,0,0,0.3);"),
106 | "\\n[:space:]")
107 | }
108 |
109 | # if the image is from a url do this thing so it works in {gt}
110 | if(!is.null(img)) {
111 | if(!str_detect(img, "http")) {
112 | uri <- gt:::get_image_uri(img)
113 | } else {
114 | uri <- img
115 | }
116 | }
117 |
118 | # make the table
119 | tibble(
120 | id = 1:length(pal),
121 | pal = pal
122 | ) |>
123 | mutate(
124 | row = ceiling(id/ncols),
125 | col = (id-1) %% ncols + 1,
126 | col = ifelse(row %% 2 == 0, max(col) - col + 1, col)
127 | ) |>
128 | select(row, col, pal) |>
129 | pivot_wider(id_cols = row, names_from = "col", values_from = "pal") |>
130 | select(-row) |>
131 | gt() |>
132 | tab_style(
133 | style = cell_text(
134 | font = c(
135 | google_font(name = "Poppins"),
136 | default_fonts()
137 | )
138 | ),
139 | locations = cells_body(columns = everything())
140 | ) |>
141 | text_transform(
142 | locations = cells_body(
143 | columns = everything()
144 | ),
145 | fn = function(k, i){
146 | col_rgb <- map_chr(1:nrows, ~paste0("rgb(", paste(as.numeric(t(col2rgb(k[.x]))), collapse = ", "), ")"))
147 | map_chr(1:nrows, ~{
148 | if(is.na(k[.x])) {
149 | out <- ""
150 | } else {
151 | out <- glue("
{k[.x]}
{col_rgb[.x]}")
152 | }
153 | out
154 | })
155 | }
156 | ) |>
157 | img_header() |>
158 | tab_options(
159 | column_labels.font.size = 0,
160 | table_body.hlines.width = px(0),
161 | table_body.border.top.width = px(0),
162 | table_body.border.bottom.width = px(0),
163 | heading.border.bottom.width = px(0),
164 | table.border.bottom.width = px(0),
165 | table.border.top.width = px(0),
166 | column_labels.border.top.width = px(0),
167 | column_labels.border.bottom.width = px(0),
168 | data_row.padding = px(10),
169 | data_row.padding.horizontal = px(10)
170 | )
171 | }
172 |
173 | #' Manually sort a palette
174 | #'
175 | #' The palette is displayed in the plotting window where you can click
176 | #' the colours in the order you want to sort them. The sorted palette
177 | #' will be returned. This saves you copy/pasting hex codes in your script.
178 | #'
179 | #' @param pal Palette. Character vector of hex codes
180 | #' @param n Number of colours to choose
181 | #' @param label Label for the palette.
182 | #' @param print_output Print output to console to easily copy and paste into your script.
183 | #'
184 | #' @return Character vector
185 | #' @export
186 | #'
187 | #' @examples \dontrun{
188 | #' pal <- sample(c('#57364e', '#566f1b', '#97a258', '#cac58b', '#dbedd5'))
189 | #' sort_pal(pal)
190 | #' }
191 | sort_pal <- function(pal, n = NULL, label = NULL, print_output = TRUE) {
192 |
193 | # show initial palette for clicking on
194 | print(show_pal(pal))
195 |
196 | # loop to click on image
197 | if(is.null(n)) n <- length(pal)
198 | message(white(glue("Click {n} colours in the desired order\n\n")))
199 | pos_ls <- list()
200 | for(k in 1:n) {
201 | pos_ls[[k]] <- grid.locator(unit = "npc")
202 | cat(glue("colours sorted: {k}/{n}\r"))
203 | }
204 |
205 | # sort from user input
206 | id <- map_dbl(pos_ls, ~as.numeric(.x$x))
207 | new_pal_order <- floor(id*length(pal)) + 1
208 | pal <- pal[new_pal_order]
209 | print(show_pal(pal))
210 |
211 | # print palette code
212 | if(print_output) {
213 | cat("\n")
214 | paste_pal_code(pal, label)
215 | }
216 |
217 | pal
218 |
219 | }
220 |
221 | #' Auto palette sort
222 | #'
223 | #' Automatically sorts the palette. May not give the desired result. If not you
224 | #' can run `sort_pal()` to manually sort.
225 | #'
226 | #' @param pal Input palette
227 | #' @param label Label for the palette.
228 | #' @param plot_output Logical. Default \code{FALSE}.
229 | #'
230 | #' @return Returns a character vector of hex codes
231 | #' @export
232 | #'
233 | #' @examples
234 | #' pal <- sample(colours(), 8)
235 | #' sort_pal_auto(pal, 'test')
236 | sort_pal_auto <- function(pal, label, plot_output = FALSE) {
237 |
238 | rgb <- col2rgb(pal)
239 | tsp <- as.TSP(dist(t(rgb)))
240 | sol <- solve_TSP(tsp, control = list(repetitions = 1e3))
241 | pal <- pal[sol]
242 | x <- colSums(col2rgb(pal))
243 | max_k <- which.min(x)[1]
244 | if(max_k != 1) pal <- pal[c(max_k:length(pal), 1:(max_k-1))]
245 | if(plot_output) print(show_pal(pal))
246 |
247 | pal
248 | }
249 |
250 | #' Makes eyedroppers output
251 | #'
252 | #' Plots the palette and places the image and label over the top.
253 | #'
254 | #' @param obj Output from \code{extract_pal} or \code{eyedropper}
255 | #' @param pal Palette
256 | #' @param img_path Image path
257 | #'
258 | #' @return ggplot object
259 | make_output <- function(obj = NULL, pal, img_path) {
260 |
261 | if(!is.null(obj)) {
262 | pal <- obj$pal
263 | img_path <- obj$img_path
264 | }
265 |
266 | # read in image
267 | img_rs <- image_read(img_path)
268 | info <- image_info(img_rs)
269 | ht <- info$height
270 | wd <- info$width
271 |
272 | # temp file for output
273 | temp_output <- tempfile(fileext = ".png")
274 | temp_output_stack <- tempfile(fileext = ".png")
275 |
276 | # saving palette
277 | ggsave(plot = show_pal(pal), filename = temp_output, height = 100, width = 1000, units = "px")
278 |
279 | # stack and output
280 | img_selector <- image_append(image_scale(c(img_rs, image_read(temp_output)), "1000"), stack = TRUE)
281 | image_write(img_selector, path = temp_output_stack)
282 |
283 | ggplot() +
284 | geom_from_path(aes(wd/2, ht/2, path = temp_output_stack)) +
285 | xlim(0, wd) +
286 | ylim(0, ht) +
287 | theme_void() +
288 | theme(
289 | plot.background = element_blank()
290 | )
291 |
292 | }
293 |
294 |
295 | #' Copy + Pasteable palette vector
296 | #'
297 | #' Prints a message to console so you can easily copy and paste the palette
298 | #'
299 | #' @param pal Palette vector
300 | #' @param label Label
301 | #'
302 | #' @return a message
303 | paste_pal_code <- function(pal, label = NULL) {
304 | if(is.null(label)) label <- "pal"
305 | message(cyan(paste0("\n", to_snake_case(label)," <- c('", paste0(pal, collapse = "', '"), "')\n")))
306 | }
307 |
308 |
309 | #' Choose font colour
310 | #'
311 | #' @param bg Background
312 | #' @param light The light text colour
313 | #' @param dark The dark text colour
314 | #' @param threshold The threshold for switching
315 | #'
316 | #' @return hex code
317 | choose_font_colour <- function(bg, light = "#ffffff", dark = "#000000", threshold = 170) {
318 | x <- drop(c(0.299, 0.587, 0.114) %*% col2rgb(bg) > threshold)
319 | out <- ifelse(x, dark, light)
320 | ifelse(is.na(bg), light, out)
321 | }
322 |
323 |
324 | #' Modify the saturation of a colour palette
325 | #'
326 | #' @param cols Vector of colours
327 | #' @param sat Factor to adjust the saturation
328 | #'
329 | #' @importFrom grDevices rgb2hsv hsv
330 | #'
331 | #' @return A vector of hex codes
332 | #' @export
333 | modify_saturation <- function(cols, sat = 1.2) {
334 | X <- diag(c(1, sat, 1)) %*% rgb2hsv(col2rgb(cols))
335 | hsv(X[1,], pmin(X[2,], 1), X[3,])
336 | }
337 |
338 |
339 | #' Min-max scale function
340 | #'
341 | #' @param x Vector of values
342 | #' @param a Min
343 | #' @param b Max
344 | #' @param a0 Min bound
345 | #' @param b0 Max bound
346 | #'
347 | #' @return numeric vector
348 | min_max <- function(x, a, b, a0 = NULL, b0 = NULL) {
349 | if(is.null(a0) & is.null(b0)) {
350 | a0 <- min(x)
351 | b0 <- max(x)
352 | }
353 | (b - a) * (x - a0) / (b0 - a0) + a
354 | }
355 |
--------------------------------------------------------------------------------
/R/pencil-case.R:
--------------------------------------------------------------------------------
1 | #' Pencil Case
2 | #'
3 | #' A list of palettes
4 | #'
5 | #' @importFrom purrr map_dfr
6 | #'
7 | #' @export
8 | pencil_case <- list(
9 | secret_of_mana = list(
10 | cat = c('#E92E2C', '#F1E32F', '#91A14A', '#373321')
11 | ),
12 | super_mario_world = list(
13 | cat = c('#37e605', '#0d6cfd', '#fdfc05', '#fe0000')
14 | ),
15 | super_ghouls_and_ghosts = list(
16 | cat = c('#CF2023', '#EF7434', '#89883D', '#6C6E85')
17 | ),
18 | super_probotector = list(
19 | div = c('#373140', '#79484D', '#CB4C45', '#E09D5C', '#E1D4C8', '#9C99A9', '#536E9A', '#134B8A'),
20 | cat = c('#373140', '#134B8A', '#9C99A9', '#CB4C45')
21 | ),
22 | paw_patrol = list(
23 | cat = c('#11c1b9', '#fde55d', '#f13837', '#2f406e', '#f37c3e', '#6fb455', '#b4485e')
24 | ),
25 | skittles = list(
26 | cat = c('#05beed', '#10df0b', '#fdf405', '#f67a19', '#f11941')
27 | ),
28 | bright = list(
29 | cat = c("#540d6e", "#ee4266", "#ffd23f", "#3bceac")
30 | ),
31 | blue_pink = list(
32 | cat = c('#587DB3', '#42BFDD', '#BBE6E4', '#F0F6F6', '#FF66B3')
33 | ),
34 | blue_orange = list(
35 | cat = c('#244157', '#219ebc', '#88B2C7', '#ffb703', '#fb8500', '#AD5A00')
36 | ),
37 | prgr = list(
38 | div = c('#231942', '#3D3364', '#584E87', '#7566A0', '#937CB6', '#AAA1BC', '#BDD0B7', '#BFE7B2', '#A6DCAE', '#8ACFAB', '#5FBFAB', '#35B0AB')
39 | ),
40 | lakes = list(
41 | cat = c("#788FCE", "#e07a5f", "#f2cc8f", "#81b29a", "#f4f1de")
42 | ),
43 | spec = list(
44 | div = c("#005f73", "#0a9396", "#94d2bd", "#e9d8a6", "#ee9b00", "#ca6702", "#bb3e03", "#ae2012", "#9b2226")
45 | ),
46 | d5 = list(
47 | cat = c("#ef476f", "#ffd166", "#06d6a0", "#118ab2", "#073b4c")
48 | ),
49 | d10 = list(
50 | cat = c("#788FCE", "#BD8184", "#E6956F", "#F2CC8F", "#A6BA96", "#C5E8E3", "#F4F1DE", "#CDC3D4", "#A88AD2", "#60627C")
51 | ),
52 | mt_fuji = list(
53 | cat = c("#3F3A3F", "#AF8290", "#D3C6DA", "#6F96D0")
54 | ),
55 | remission = list(
56 | div = c('#5C4155', '#865D7B', '#98819D', '#7791A8', '#446783', '#2F485C'),
57 | cat = c('#61542a', '#446783', '#865d7b', '#0a080b', '#7791a8', '#98819d', '#8996a7', '#352b43'),
58 | seq = c('#0a080b', '#352b43', '#865d7b', '#98819d')
59 | ),
60 | leviathan = list(
61 | cat = c('#66211C', '#7C6A3F', '#0C87A2', '#355355'),
62 | seq = c('#C2D2D0', '#97AFAE', '#5F8B8C', '#355355')
63 | ),
64 | crack_the_skye = list(
65 | cat = c('#912716', '#bf7b29', '#4b7d57', '#2f3c68', '#8d7ca9', '#b2b7a6', '#332b28', '#151413')
66 | ),
67 | once_more_around_the_sun = list(
68 | div = c('#720F08', '#C41C0C', '#C47020', '#90952E', '#4D732F', '#2A4831'),
69 | cat = c('#151412', '#720f08', '#d9200d', '#b7a62e', '#cecfc0', '#769879', '#577e2f', '#2a4831')
70 | ),
71 | emperor_of_sand = list(
72 | div = c('#392B26', '#614640', '#978E86', '#EBD0A2', '#F6B45C', '#EF7945', '#C86446', '#984E3A'),
73 | seq = c('#EBD0A2', '#F6B45C', '#EF7945', '#C86446', '#984E3A')
74 | ),
75 | mountains_in_autumn = list(
76 | div = c('#965b0d', '#c06e08', '#da980a', '#355238', '#093c34', '#131c0d'),
77 | cat = c('#c06e08', '#da980a', '#68603c', '#355238', '#093c34', '#131c0d', '#245f84', '#3298d1')
78 | ),
79 | jupiter = list(
80 | div = c('#38343a', '#564b4a', '#d2bca8', '#c59784', '#9c6861')
81 | ),
82 | colorado_mountains = list(
83 | div = c('#49392D', '#664F3D', '#826952', '#9D8468', '#C8A887', '#D8D2CC', '#919AA0', '#545E5F', '#384945', '#1D3335'),
84 | cat = c('#0F1713', '#2B291F', '#49392D', '#664F3D', '#826952', '#9D8468', '#C8A887', '#D8D2CC', '#919AA0', '#545E5F', '#384945', '#1D3335')
85 | ),
86 | graffiti = list(
87 | div = c('#2A1E0F', '#516367', '#7AA3BA', '#D4E2E4', '#E1CF8C', '#CBAA4C', '#BE8311', '#7C490E'),
88 | seq = c('#E1CF8C', '#CBAA4C', '#BE8311', '#7C490E')
89 | )
90 | )
91 |
92 |
93 | #' Shows all palettes in the pencil case
94 | #'
95 | #' @param offset Controls the overlapping circles
96 | #'
97 | #' @return graphic of colour palettes
98 | #' @export
99 | #'
100 | #' @importFrom gt cols_hide cols_width
101 | #'
102 | #' @examples
103 | #' show_pencil_case()
104 | show_pencil_case <- function(offset = 50) {
105 | df <- map_dfr(1:length(pencil_case), ~{
106 | pal <- pencil_case[[.x]][[1]]
107 | bg <- map_chr(2:length(pal), function(k) {
108 | glue("{(k-1)*offset}px 0 0 -1px {pal[k]}")
109 | }) |>
110 | paste0(collapse = ", ")
111 |
112 | tibble(
113 | id = .x,
114 | name = snakecase::to_title_case(names(pencil_case)[[.x]]),
115 | first = pal[1],
116 | bg = bg
117 | )
118 | })
119 |
120 | df |>
121 | gt() |>
122 | cols_width(
123 | bg ~ px(700)
124 | ) |>
125 | text_transform(
126 | fn = function(k, i) {
127 | glue("")
133 | },
134 | locations = cells_body(
135 | columns = bg
136 | )
137 | ) |>
138 | tab_style(
139 | style = cell_text(
140 | size = px(24),
141 | align = "right",
142 | font = c(
143 | google_font(name = "Lexend"),
144 | default_fonts()
145 | )
146 | ),
147 | locations = cells_body(columns = c(id, name))
148 | ) |>
149 | cols_hide("first") |>
150 | tab_options(
151 | column_labels.font.size = 0,
152 | table_body.hlines.width = px(0),
153 | table_body.border.top.width = px(0),
154 | table_body.border.bottom.width = px(0),
155 | heading.border.bottom.width = px(0),
156 | table.border.bottom.width = px(0),
157 | table.border.top.width = px(0),
158 | column_labels.border.top.width = px(0),
159 | column_labels.border.bottom.width = px(0),
160 | data_row.padding = px(10),
161 | data_row.padding.horizontal = px(10)
162 | )
163 | }
164 |
165 | #' Easily get a palette from the pencil case
166 | #'
167 | #' @param id Number
168 | #'
169 | #' @return A vector of hexcodes
170 | #' @export
171 | #'
172 | #' @examples
173 | #' palette(1)
174 | palette <- function(id) {
175 | pencil_case[[id]][[1]]
176 | }
177 |
--------------------------------------------------------------------------------
/README.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | output: github_document
3 | ---
4 |
5 | # eyedroppeR
6 |
7 | There are fancy ways to extract colours from images but sometimes it's easier if you could simply click on the image and choose the colours you want.
8 |
9 | With `eyedroppeR` you can click on the image and it will return the hex codes of the selected pixel all within R.
10 |
11 | ## Installation
12 |
13 | ```{r, eval = FALSE}
14 | devtools::install_github("doehm/eyedroppeR")
15 | ```
16 |
17 | ## Usage
18 |
19 | Use `eyedropper` with the following steps:
20 |
21 | 1. Find the image you want to pick colours from online. Local images cn be used as well.
22 | 2. Right-click and 'copy image address'. As an example copy the following image (right-click > copy image address).
23 |
24 |
25 |
26 | 3. Choose how many colours to pick e.g. `n = 8`.
27 | 4. Run `eyedropper(n = 8, img_path = '', label = "Sunset on the South Coast")`.
28 | 5. If it's the first time you have run `eyedropper` complete the calibration setup. It only needs to be done once, just click the top dot and then the bottom dot. (This is temporary until I find an automated way to do it that works for everyone's system setup. It only takes a few seconds, and trust me it's more efficient than selecting the wrong colours and trying to work out why.)
29 |
30 |
31 |
32 |
33 |
34 | 6. Click the 8 desired colours. You can click on either the image itself or the swatch at the bottom. The image will be stretched to the borders of the window, but that's OK.
35 | 7. Done! Copy the returned string and add it to your script and start using `pal`.
36 |
37 |
38 |
39 | The palette, image that is saved at the temporary address, and the label will also be returned by the function. It will also output to console a message that can be copied and pasted directly to your code. That's the best part!
40 |
41 |
42 | ## Use `pixelate` to easily select the right colour
43 |
44 | By setting `pixelate = TRUE` the original image will be converted to a low resolution so that it's easily to select the right colour. The default pixelation is set to 40 (pixels on the x and y). You can adjust that higher or lower as needed.
45 |
46 |
47 |
48 |
49 | ```{r, eval = FALSE}
50 | eyedropper(n = 5, img_path = '', pixelate = TRUE)
51 | ```
52 |
53 |
54 |
55 |
56 |
57 | When `pixelate` is the swatch banner at the bottom won't be displayed because it's not really needed.
58 |
59 | ## Automatically extract a palette with `extract_pal`
60 |
61 | To speed up the process and if you're not looking for specific colours you can run `extract_pal` to automatically select some for you.
62 |
63 | ```{r, eval = FALSE}
64 |
65 | library(eyedroppeR)
66 |
67 | path <- "https://github.com/doehm/eyedroppeR/blob/main/dev/images/belize.jpg?raw=true"
68 | extract_pal(12, path, label = "Caye Caulker, Belize")
69 |
70 | ```
71 |
72 |
73 |
74 | ```
75 | caye_caulker_belize <- c('#477d7c', '#4f967e', '#a1d6f5', '#cbe8f4', '#f0e4c6', '#d8c09c', '#adae46', '#a6954f', '#e14f16', '#a92613', '#cf4959', '#d78462')
76 |
77 | $label
78 | [1] "Caye Caulker, Belize"
79 |
80 | $pal
81 | [1] "#477d7c" "#4f967e" "#a1d6f5" "#cbe8f4" "#f0e4c6" "#d8c09c" "#adae46" "#a6954f" "#e14f16" "#a92613"
82 | [11] "#cf4959" "#d78462"
83 |
84 | $img_path
85 | [1] "C:\\Users\\Dan\\AppData\\Local\\Temp\\RtmpIN1NcN\\file70302f63b83"
86 | ```
87 |
88 |
89 | Often you won't quite get what you're after and you'll want to use `eyedropper` instead.
90 |
91 | ## Use `swatch()` to view a palette
92 |
93 | ```{r, echo = FALSE}
94 | suppressPackageStartupMessages(library(eyedroppeR))
95 | ```
96 |
97 |
98 | ```{r, eval=FALSE}
99 | path <- "https://github.com/doehm/eyedroppeR/blob/main/dev/images/belize.jpg?raw=true"
100 | x <- extract_pal(4, path)
101 |
102 | swatch(x$pal, path)
103 | ```
104 |
105 |
106 |
107 | ## Other functions
108 |
109 | * `sort_pal`: Allows you to manually sort a palette by clicking on the colours in order. It also allows you to select a specified number of colours if you don't want them all.
110 |
111 | * `show_pencil_case`: There are a bunch of palettes stored in the `pencil_case`. This will plot them all so you can easily choose the one you want.
112 |
113 | * `palette`: Helper to read a palette from the `pencil_case`. e.g. `palette(1)`
114 |
115 | ## Palettes in the `pencil_case`
116 |
117 | ```{r, eval=FALSE}
118 | show_pencil_case()
119 | ```
120 |
121 |
122 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # eyedroppeR
3 |
4 | There are fancy ways to extract colours from images but sometimes it’s
5 | easier if you could simply click on the image and choose the colours you
6 | want.
7 |
8 | With `eyedroppeR` you can click on the image and it will return the hex
9 | codes of the selected pixel all within R.
10 |
11 | ## Installation
12 |
13 | ``` r
14 | devtools::install_github("doehm/eyedroppeR")
15 | ```
16 |
17 | ## Usage
18 |
19 | Use `eyedropper` with the following steps:
20 |
21 | 1. Find the image you want to pick colours from online. Local images cn
22 | be used as well.
23 |
24 | 2. Right-click and ‘copy image address’. As an example copy the
25 | following image (right-click \> copy image address).
26 |
27 |
28 |
29 | 3. Choose how many colours to pick e.g. `n = 8`.
30 |
31 | 4. Run
32 | `eyedropper(n = 8, img_path = '', label = "Sunset on the South Coast")`.
33 |
34 | 5. If it’s the first time you have run `eyedropper` complete the
35 | calibration setup. It only needs to be done once, just click the top
36 | dot and then the bottom dot. (This is temporary until I find an
37 | automated way to do it that works for everyone’s system setup. It
38 | only takes a few seconds, and trust me it’s more efficient than
39 | selecting the wrong colours and trying to work out why.)
40 |
41 |
42 |
43 |
44 |
45 | 6. Click the 8 desired colours. You can click on either the image
46 | itself or the swatch at the bottom. The image will be stretched to
47 | the borders of the window, but that’s OK.
48 |
49 | 7. Done! Copy the returned string and add it to your script and start
50 | using `pal`.
51 |
52 |
53 |
54 | The palette, image that is saved at the temporary address, and the label
55 | will also be returned by the function. It will also output to console a
56 | message that can be copied and pasted directly to your code. That’s the
57 | best part!
58 |
59 | ## Use `pixelate` to easily select the right colour
60 |
61 | By setting `pixelate = TRUE` the original image will be converted to a
62 | low resolution so that it’s easily to select the right colour. The
63 | default pixelation is set to 40 (pixels on the x and y). You can adjust
64 | that higher or lower as needed.
65 |
66 |
67 |
68 | ``` r
69 | eyedropper(n = 5, img_path = '', pixelate = TRUE)
70 | ```
71 |
72 |
73 |
74 |
75 |
76 | When `pixelate` is the swatch banner at the bottom won’t be displayed
77 | because it’s not really needed.
78 |
79 | ## Automatically extract a palette with `extract_pal`
80 |
81 | To speed up the process and if you’re not looking for specific colours
82 | you can run `extract_pal` to automatically select some for you.
83 |
84 | ``` r
85 | library(eyedroppeR)
86 |
87 | path <- "https://github.com/doehm/eyedroppeR/blob/main/dev/images/belize.jpg?raw=true"
88 | extract_pal(12, path, label = "Caye Caulker, Belize")
89 | ```
90 |
91 |
92 |
93 | caye_caulker_belize <- c('#477d7c', '#4f967e', '#a1d6f5', '#cbe8f4', '#f0e4c6', '#d8c09c', '#adae46', '#a6954f', '#e14f16', '#a92613', '#cf4959', '#d78462')
94 |
95 | $label
96 | [1] "Caye Caulker, Belize"
97 |
98 | $pal
99 | [1] "#477d7c" "#4f967e" "#a1d6f5" "#cbe8f4" "#f0e4c6" "#d8c09c" "#adae46" "#a6954f" "#e14f16" "#a92613"
100 | [11] "#cf4959" "#d78462"
101 |
102 | $img_path
103 | [1] "C:\\Users\\Dan\\AppData\\Local\\Temp\\RtmpIN1NcN\\file70302f63b83"
104 |
105 |
106 |
107 | Often you won’t quite get what you’re after and you’ll want to use
108 | `eyedropper` instead.
109 |
110 | ## Use `swatch()` to view a palette
111 |
112 | ``` r
113 | path <- "https://github.com/doehm/eyedroppeR/blob/main/dev/images/belize.jpg?raw=true"
114 | x <- extract_pal(4, path)
115 |
116 | swatch(x$pal, path)
117 | ```
118 |
119 |
120 |
121 | ## Other functions
122 |
123 | - `sort_pal`: Allows you to manually sort a palette by clicking on the
124 | colours in order. It also allows you to select a specified number of
125 | colours if you don’t want them all.
126 |
127 | - `show_pencil_case`: There are a bunch of palettes stored in the
128 | `pencil_case`. This will plot them all so you can easily choose the
129 | one you want.
130 |
131 | - `palette`: Helper to read a palette from the `pencil_case`.
132 | e.g. `palette(1)`
133 |
134 | ## Palettes in the `pencil_case`
135 |
136 | ``` r
137 | show_pencil_case()
138 | ```
139 |
140 |
141 |
--------------------------------------------------------------------------------
/cran-comments.md:
--------------------------------------------------------------------------------
1 | ## R CMD check results
2 |
3 | 0 errors | 0 warnings | 0 note
4 |
5 | * This is a new release.
6 |
7 | ## Test environments
8 |
9 | rhub:
10 | * x86_64-w64-mingw32 (64-bit)
11 | * Windows Server 2022, R-devel, 64 bit
12 | * Ubuntu Linux 20.04.1 LTS, R-release, GCC
13 | * Fedora Linux, R-devel, clang, gfortran
14 | * Debian Linux, R-devel, clang, ISO-8859-15 locale
15 | * Debian Linux, R-devel, GCC
16 | * Debian Linux, R-devel, GCC, no long double
17 | * Debian Linux, R-patched, GCC
18 | * Debian Linux, R-release, GCC
19 |
--------------------------------------------------------------------------------
/dev/images/belize-output-12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/belize-output-12.png
--------------------------------------------------------------------------------
/dev/images/belize-output-s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/belize-output-s.png
--------------------------------------------------------------------------------
/dev/images/belize-s.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/belize-s.jpg
--------------------------------------------------------------------------------
/dev/images/belize-swatch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/belize-swatch.png
--------------------------------------------------------------------------------
/dev/images/belize.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/belize.jpg
--------------------------------------------------------------------------------
/dev/images/calibrate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/calibrate.png
--------------------------------------------------------------------------------
/dev/images/cat4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/cat4.png
--------------------------------------------------------------------------------
/dev/images/catedral-s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/catedral-s.png
--------------------------------------------------------------------------------
/dev/images/eyedropper.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/eyedropper.gif
--------------------------------------------------------------------------------
/dev/images/eyedropper1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/eyedropper1.jpg
--------------------------------------------------------------------------------
/dev/images/feature.png.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/feature.png.png
--------------------------------------------------------------------------------
/dev/images/hex-amatic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/hex-amatic.png
--------------------------------------------------------------------------------
/dev/images/misc/graffiti.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/misc/graffiti.png
--------------------------------------------------------------------------------
/dev/images/mountains-in-autumn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/mountains-in-autumn.png
--------------------------------------------------------------------------------
/dev/images/mountains-selector.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/mountains-selector.png
--------------------------------------------------------------------------------
/dev/images/mountains.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/mountains.png
--------------------------------------------------------------------------------
/dev/images/pencil-case/mastodon-blood-mountain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/pencil-case/mastodon-blood-mountain.png
--------------------------------------------------------------------------------
/dev/images/pencil-case/mastodon-crack-the-skye.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/pencil-case/mastodon-crack-the-skye.png
--------------------------------------------------------------------------------
/dev/images/pencil-case/mastodon-empoeror-of-sands.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/pencil-case/mastodon-empoeror-of-sands.png
--------------------------------------------------------------------------------
/dev/images/pencil-case/mastodon-hushed-and-grim.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/pencil-case/mastodon-hushed-and-grim.png
--------------------------------------------------------------------------------
/dev/images/pencil-case/mastodon-leviathan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/pencil-case/mastodon-leviathan.png
--------------------------------------------------------------------------------
/dev/images/pencil-case/mastodon-once-more-around-the-sun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/pencil-case/mastodon-once-more-around-the-sun.png
--------------------------------------------------------------------------------
/dev/images/pencil-case/mastodon-remission.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/pencil-case/mastodon-remission.png
--------------------------------------------------------------------------------
/dev/images/pencil-case/mastodon-the-hunter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/pencil-case/mastodon-the-hunter.png
--------------------------------------------------------------------------------
/dev/images/pencil-case/motley-crue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/pencil-case/motley-crue.png
--------------------------------------------------------------------------------
/dev/images/pencil-case/mountains-in-autumn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/pencil-case/mountains-in-autumn.png
--------------------------------------------------------------------------------
/dev/images/pencil-case/tool-10000-days.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/pencil-case/tool-10000-days.png
--------------------------------------------------------------------------------
/dev/images/pencil-case/tool-fear-inoculum.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/pencil-case/tool-fear-inoculum.png
--------------------------------------------------------------------------------
/dev/images/pencil-case/tool-lateralus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/pencil-case/tool-lateralus.png
--------------------------------------------------------------------------------
/dev/images/show-pencil-case.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/show-pencil-case.png
--------------------------------------------------------------------------------
/dev/images/snes/mana.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/snes/mana.png
--------------------------------------------------------------------------------
/dev/images/snes/secret-of-mana-40p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/snes/secret-of-mana-40p.png
--------------------------------------------------------------------------------
/dev/images/snes/secret-of-mana-80p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/snes/secret-of-mana-80p.png
--------------------------------------------------------------------------------
/dev/images/snes/secret-of-mana-og.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/snes/secret-of-mana-og.png
--------------------------------------------------------------------------------
/dev/images/snes/secret-of-mana.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/snes/secret-of-mana.png
--------------------------------------------------------------------------------
/dev/images/sunset-sampler-s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/sunset-sampler-s.png
--------------------------------------------------------------------------------
/dev/images/sunset-sampler.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/sunset-sampler.png
--------------------------------------------------------------------------------
/dev/images/sunset-south-coast-output-s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/sunset-south-coast-output-s.png
--------------------------------------------------------------------------------
/dev/images/sunset-south-coast-output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/sunset-south-coast-output.png
--------------------------------------------------------------------------------
/dev/images/sunset-south-coast-s.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/sunset-south-coast-s.jpg
--------------------------------------------------------------------------------
/dev/images/sunset-south-coast.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/dev/images/sunset-south-coast.jpg
--------------------------------------------------------------------------------
/dev/scripts/dev.R:
--------------------------------------------------------------------------------
1 |
2 | library(tidyverse)
3 | library(magick)
4 | library(grid)
5 | library(gridExtra)
6 |
7 | img_path <- "dev/images/test.png"
8 |
9 | ggplot() +
10 | ggpubr::background_image(image_read(img_path))
11 |
12 | n <- 6
13 | eye_ls <- list()
14 | for(k in 1:n) {
15 | eye_ls[[k]] <- grid::grid.locator(unit = "npc")
16 | }
17 |
18 | eye_ls
19 | pal <- map_chr(eye_ls, ~{
20 | coords <- as.numeric(str_remove(reduce(.x, c), "npc"))
21 | coords[2] <- 2-coords[2]
22 | img_dat <- image_data(image_read(img_path))
23 | dims <- dim(img_dat)
24 | xpx <- round(coords[1]*dims[2])
25 | ypx <- round(coords[2]*dims[3])
26 | paste0("#", paste0(img_dat[, xpx, ypx][1:3], collapse = ""))
27 | })
28 |
29 | scales::show_col(pal)
30 |
31 |
32 | g1 <- tibble(
33 | x = 1:length(x),
34 | y = 1
35 | ) |>
36 | ggplot() +
37 | geom_chicklet(aes(x, y), fill = x, radius = grid::unit(9, "pt")) +
38 | theme_void()
39 |
40 | g2 <- ggplot() +
41 | ggpath::geom_from_path(aes(0, 0, path = path), width = 0.9) +
42 | theme_void()
43 |
44 | g2 + g1
45 |
46 |
47 |
48 |
49 | # 🔪 hex ------------------------------------------------------------------
50 |
51 | library(showtext)
52 | library(ggtext)
53 |
54 | font_add_google("Caveat", "caveat")
55 | font_add("fa-solid", regular = "C:/Users/Dan/Documents/R/repos/survivorDev/assets/fonts/fontawesome-free-6.2.0-web/webfonts/fa-solid-900.ttf")
56 | showtext_auto()
57 |
58 | txt <- "grey20"
59 | icon <- glue("")
60 |
61 | ggplot() +
62 | geom_from_path(aes(0, -0.1, path = "dev/images/eyedropper.jpg")) +
63 | geom_richtext(aes(0, -0.05, label = icon), size = 100, label.color = NA, fill = NA) +
64 | geom_text(aes(0, -0.2, label = "eyedroppeR"), colour = txt, size = 48, fontface = "bold", family = "caveat") +
65 | # annotate("rect", xmin = 1, xmax = length(pal), ymin = 0.45, ymax = 0.55, fill = "grey90", alpha = 0.5) +
66 | # annotate("text", (length(pal)+1)/2, y = 0.5, label = "---- palette ----", size = 12) +
67 | ylim(-0.5, 0.3) +
68 | theme_void() +
69 | theme(plot.background = element_rect(fill = "skyblue"))
70 |
71 | ggsave("dev/images/hex.png", height = 5, width = 5)
72 |
73 | image_read(cropcircles::hex_crop("dev/images/hex.png")) |>
74 | image_write("dev/images/hex1.png")
75 |
76 |
77 |
78 | # sort pal ----------------------------------------------------------------
79 |
80 | pal <- y
81 |
82 | show_pal(pal)
83 |
84 | pos_ls <- list()
85 | for(k in 1:length(pal)) {
86 | pos_ls[[k]] <- grid::grid.locator(unit = "npc")
87 | }
88 |
89 | id <- as.numeric(map_chr(pos_ls, "x"))
90 | new_pal <- purrr::map_dbl(id, ~which(sort(id) == .x))
91 | show_pal(pal[new_pal])
92 |
93 |
94 | pal <- c('#F4F3E6', '#DDC6B3', '#AD908D', '#866D6C', '#664B39', '#040305', '#C57850', '#1B1B1F', '#35140E', '#698795', '#36353D', '#664B39', '#9C5B37', '#698795', '#EC5921', '#C8121F', '#621615', '#97201A', '#F00C1D', '#565171', '#040305')
95 |
--------------------------------------------------------------------------------
/dev/scripts/hex.R:
--------------------------------------------------------------------------------
1 | library(magick)
2 | library(cropcircles)
3 | library(ggtext)
4 |
5 | img <- image_read("dev/images/eyedropper1.jpg")
6 |
7 | img_crop <- hex_crop(img, border_size = 16)
8 |
9 | image_read(img_crop)
10 |
11 | font_add("fa-brands", regular = "C:/Users/Dan/Documents/R/repos/survivorDev/assets/fonts/fontawesome-free-6.2.0-web/webfonts/fa-brands-400.ttf")
12 | font_add("fa-solid", regular = "C:/Users/Dan/Documents/R/repos/survivorDev/assets/fonts/fontawesome-free-6.2.0-web/webfonts/fa-solid-900.ttf")
13 | font_add("fa-reg", regular = "C:/Users/Dan/Documents/R/repos/survivorDev/assets/fonts/fontawesome-free-6.2.0-web/webfonts/fa-regular-400.ttf")
14 | mastodon <- glue("")
15 | twitter <- glue("")
16 | github <- glue("")
17 | space <- glue("'")
18 | space2 <- glue("--") # can't believe I'm doing this
19 | caption <- glue("{mastodon}{space2}@danoehm@{space}fosstodon.org{space2}{twitter}{space2}@danoehm{space2}{github}{space2}doehm/tidytuesday{space2}{floppy}{space2}Bob Ross Paintings data")
20 |
21 |
22 | library(showtext)
23 |
24 | font_add_google("Amatic SC", "amatic")
25 | showtext_auto()
26 | ft <- "amatic"
27 |
28 | ggplot() +
29 | geom_from_path(aes(0.5, 0.5, path = img_crop)) +
30 | annotate("text", x=0.68, y = 0.2, label = "EYEDROPPER", family = ft, size = 70, angle = 30, colour = "black", fontface = "bold") +
31 | annotate("richtext", x=0.51, y = 0.005, label = " doehm/eyedroppeR",
32 | family = ft, size = 14, angle = 30, colour = "black", fontface = "bold", hjust = 0, label.color = NA, fill = NA) +
33 | xlim(0, 1) +
34 | ylim(0, 1) +
35 | theme_void()
36 |
37 | ggsave("dev/images/hex-amatic.png", height = 6, width = 6)
38 | image_read("dev/images/hex-amatic.png") |>
39 | image_fill("none", fuzz = 10) |>
40 | image_fill("none", point = "+1000+5", fuzz = 10) |>
41 | image_write("dev/images/hex-amatic.png")
42 |
--------------------------------------------------------------------------------
/dev/scripts/show-pal.R:
--------------------------------------------------------------------------------
1 |
2 | library(ggforce)
3 | library(ggfx)
4 | library(dplyr)
5 | library(tidyr)
6 | library(gt)
7 | library(gtExtras)
8 | library(stringr)
9 | library(magick)
10 | library(showtext)
11 |
12 | font_add_google("Poppins", "poppins")
13 | showtext_auto()
14 |
15 | x <- generate_palette(4, "anime style picture, hi-res, japanese cherry blossoms and mount fuji")
16 | pal <- x$pal
17 | pal <- c('#3F3A3F', '#AF8290', '#D3C6DA', '#6F96D0')
18 | swatch(pal, x$eyedropper$img_path, .padding = 4)
19 |
20 | swatch(pal, "C:\\Users\\danie\\AppData\\Local\\Temp\\RtmpKan5Pm\\file64a02c6c5ea7", .padding = 4)
21 |
22 | x <- extract_pal(6, "https://i.ebayimg.com/images/g/ZJIAAOSwvsVkPy-Z/s-l1600.jpg")
23 | swatch(x$pal, x$img_path, .padding = 1)
24 |
25 | pal <- x$pal[c(1, 3, 6, 8)]
26 | ft <- "poppins"
27 | txt <- c(4, 4, 1, 1)
28 | .folder <- "misty-forest"
29 |
30 | for(k in 1:length(pal)) {
31 |
32 | .rgb <- paste0(as.numeric(t(col2rgb(pal[k]))), collapse = ", ")
33 |
34 | ggplot() +
35 | geom_circle(aes(x0 = 0.5, y0 = 0.5, r = 0.5), fill = pal[k], colour = NA) +
36 | annotate("text", x = 0.5, y = 0.84, label = "Hex", colour = pal[txt[k]], family = ft, size = 20) +
37 | annotate("text", x = 0.5, y = 0.8, label = pal[k], colour = pal[txt[k]], family = ft, size = 32) +
38 | annotate("text", x = 0.5, y = 0.74, label = "RGB", colour = pal[txt[k]], family = ft, size = 20) +
39 | annotate("text", x = 0.5, y = 0.7, label = .rgb, colour = pal[txt[k]], family = ft, size = 32) +
40 | xlim(0, 1) +
41 | ylim(0, 1) +
42 | theme_void()
43 |
44 | ggsave(glue("C:/Users/danie/OneDrive/Pictures/palettes/{.folder}/swatch-{k}.png"), height = 9, width = 9)
45 |
46 | }
47 |
48 |
49 |
50 |
51 | # urls --------------------------------------------------------------------
52 |
53 | urls <- list(
54 | super_mario_world = "https://i.ebayimg.com/images/g/ZJIAAOSwvsVkPy-Z/s-l1600.jpg",
55 | secret_of_mana = "https://i.ebayimg.com/images/g/vMAAAOSwi85dfvZb/s-l1200.jpg",
56 | super_ghouls_and_ghosts = "https://i.ebayimg.com/images/g/DmQAAOSwH~5kXsAY/s-l1200.webp",
57 | super_probotector = "C:/Users/danie/OneDrive/Pictures/palettes/super-probotector/box-art.png"
58 | )
59 |
60 | # swatches ----------------------------------------------------------------
61 |
62 | swatch(pencil_case$super_mario_world$cat, urls$super_mario_world, .padding = 4, .radius = 5)
63 | swatch(pencil_case$secret_of_mana$cat, urls$secret_of_mana, .padding = 4, .radius = 5)
64 | swatch(pencil_case$super_ghouls_and_ghosts$cat, urls$super_ghouls_and_ghosts, .padding = 4, .radius = 5)
65 | swatch(pencil_case$super_probotector$cat, urls$super_probotector, .padding = 4, .radius = 5)
66 |
67 |
68 |
69 | css <- str_remove_all("width: 115px;
70 | height: 100px;
71 | background-image:
72 | radial-gradient(circle at 50px 50px, #F00 0, #F00 50px, transparent 50px),
73 | radial-gradient(circle at 55px 50px, #FF0 0, #FF0 50px, transparent 50px),
74 | radial-gradient(circle at 60px 50px, #080 0, #080 50px, transparent 50px),
75 | radial-gradient(circle at 65px 50px, #00F 0, #00F 50px, transparent 50px);", "\\n[:space:]")
76 |
77 | tibble(x = glue("")) |>
78 | gt() |>
79 | text_transform(
80 | fn = function(x) {
81 | gt::html(x)
82 | },
83 | locations = cells_body(
84 | columns = everything()
85 | )
86 | )
87 | glue("")
88 |
89 | tibble(x = "hi") |>
90 | gt() |>
91 | text_transform(
92 | fn = function(k) {
93 | gt::html(glue(""))
101 | },
102 | locations = cells_body(
103 | columns = everything()
104 | )
105 | ) |>
106 | tab_options(data_row.padding.horizontal = px(100))
107 |
108 |
109 |
110 | pal <- pencil_case$secret_of_mana$cat
111 | map_chr(1:length(pal), function(k) {
112 | glue("{k*offset}px 0 0 -{k}px {pal[k]}")
113 | }) |>
114 | paste0(collapse = ", ")
115 |
116 |
117 |
118 |
--------------------------------------------------------------------------------
/dev/scripts/tests.R:
--------------------------------------------------------------------------------
1 |
2 | test_pal <- function(.label) {
3 |
4 | iris <- iris |>
5 | janitor::clean_names() |>
6 | as_tibble()
7 |
8 | g_hist <- ggplot() +
9 | geom_histogram(aes(displ, fill = class), mpg, colour = "black") +
10 | scale_fill_manual(values = pencil_case[[.label]]$cat) +
11 | theme_minimal()
12 |
13 | g_point <- ggplot() +
14 | geom_point(aes(petal_length, petal_width, colour = species), iris, size = 5, alpha = 0.5) +
15 | scale_colour_manual(values = pencil_case[[.label]]$cat) +
16 | theme_minimal()
17 |
18 | print(g_hist + g_point)
19 | }
20 |
21 | test_pal("remission")
22 | test_pal("leviathan")
23 |
--------------------------------------------------------------------------------
/dev/scripts/tsp.R:
--------------------------------------------------------------------------------
1 | # tsp
2 |
3 | pal <- c('#211B1F', '#515979', '#98B878', '#CBD293', '#EEEEB6', '#C4A65F', '#7B8747', '#605216')
4 | show_pal(pal[-7])
5 | pal <- c('#283746', '#A74822', '#E7DBB8', '#BCB297', '#868D8C', '#576570', '#155EB2', '#11437D')
6 | pal <- sample(pal, 8)
7 |
8 | sort_on <- c("r", "g", "b", "h", "s", "v")
9 | sort_on <- c("r", "v")
10 |
11 | # convert to rgb
12 | rgb <- col2rgb(pal)/255
13 | rownames(rgb) <- c("r", "g", "b")
14 | hsv <- rgb2hsv(rgb, maxColorValue = 1)
15 |
16 | mat <- cbind(t(rgb), t(hsv))
17 | mat <- mat[,sort_on]
18 |
19 | dmat <- as.matrix(dist(mat))
20 |
21 | total_dist <- rep(NA, length(pal))
22 | for(start in 1:length(pal)) {
23 | dmat_k <- dmat[start,]
24 | id <- sort(dmat_k, index.return = TRUE)
25 | total_dist[start] <- sum(diff(dmat[start, id$ix]))
26 | }
27 |
28 | dmat_k <- dmat[which.min(start),]
29 | id <- sort(dmat_k, index.return = TRUE)
30 | pal_ordered <- pal[id$ix]
31 | show_pal(pal_ordered)
32 |
33 |
34 | pal_ordered <- t(hsv) |>
35 | as_tibble() |>
36 | mutate(pal = pal) |>
37 | arrange(h, s, v)
38 |
39 | show_pal(pal_ordered$pal)
40 |
--------------------------------------------------------------------------------
/dev/tests/tests.R:
--------------------------------------------------------------------------------
1 |
2 | # tests
3 |
4 | # extract_pal
5 | extract_pal(7, "https://mediaproxy.tvtropes.org/width/1200/https://static.tvtropes.org/pmwiki/pub/images/tumblr_static_byogb2dbbsowcgc4gowcwwggg.jpg", "Paw Patrol")
6 |
7 | extract_pal(6, "https://mediaproxy.tvtropes.org/width/1200/https://static.tvtropes.org/pmwiki/pub/images/tumblr_static_byogb2dbbsowcgc4gowcwwggg.jpg", "Paw Patrol")
8 |
9 | extract_pal(7, "https://mediaproxy.tvtropes.org/width/1200/https://static.tvtropes.org/pmwiki/pub/images/tumblr_static_byogb2dbbsowcgc4gowcwwggg.jpg")
10 |
11 | extract_pal(7, "https://mediaproxy.tvtropes.org/width/1200/https://static.tvtropes.org/pmwiki/pub/images/tumblr_static_byogb2dbbsowcgc4gowcwwggg.jpg", print_output = FALSE)
12 |
13 |
14 | # eyedropper
15 | eyedropper(3, "https://mediaproxy.tvtropes.org/width/1200/https://static.tvtropes.org/pmwiki/pub/images/tumblr_static_byogb2dbbsowcgc4gowcwwggg.jpg", "Paw Patrol")
16 |
17 | eyedropper(4, "https://mediaproxy.tvtropes.org/width/1200/https://static.tvtropes.org/pmwiki/pub/images/tumblr_static_byogb2dbbsowcgc4gowcwwggg.jpg", "Paw Patrol")
18 |
19 | eyedropper(3, "https://mediaproxy.tvtropes.org/width/1200/https://static.tvtropes.org/pmwiki/pub/images/tumblr_static_byogb2dbbsowcgc4gowcwwggg.jpg")
20 |
21 | eyedropper(3, "https://mediaproxy.tvtropes.org/width/1200/https://static.tvtropes.org/pmwiki/pub/images/tumblr_static_byogb2dbbsowcgc4gowcwwggg.jpg", print_output = FALSE)
22 |
23 | eyedropper(3, "https://mediaproxy.tvtropes.org/width/1200/https://static.tvtropes.org/pmwiki/pub/images/tumblr_static_byogb2dbbsowcgc4gowcwwggg.jpg", calibrate = TRUE)
24 |
25 | eyedropper(3, "https://mediaproxy.tvtropes.org/width/1200/https://static.tvtropes.org/pmwiki/pub/images/tumblr_static_byogb2dbbsowcgc4gowcwwggg.jpg", pixelate = TRUE)
26 |
27 | eyedropper(3, "https://mediaproxy.tvtropes.org/width/1200/https://static.tvtropes.org/pmwiki/pub/images/tumblr_static_byogb2dbbsowcgc4gowcwwggg.jpg", pixelate = 20)
28 |
--------------------------------------------------------------------------------
/eyedroppeR.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 | ProjectId: 43c09e2c-564a-4a94-917a-74da686646a0
3 |
4 | RestoreWorkspace: Default
5 | SaveWorkspace: Default
6 | AlwaysSaveHistory: Default
7 |
8 | EnableCodeIndexing: Yes
9 | UseSpacesForTab: Yes
10 | NumSpacesForTab: 2
11 | Encoding: UTF-8
12 |
13 | RnwWeave: Sweave
14 | LaTeX: pdfLaTeX
15 |
16 | AutoAppendNewline: Yes
17 | StripTrailingWhitespace: Yes
18 |
19 | BuildType: Package
20 | PackageUseDevtools: Yes
21 | PackageInstallArgs: --no-multiarch --with-keep.source
22 | PackageRoxygenize: rd,collate,namespace,vignette
23 |
--------------------------------------------------------------------------------
/inst/images/calibration.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/inst/images/calibration.png
--------------------------------------------------------------------------------
/inst/images/hex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/inst/images/hex.png
--------------------------------------------------------------------------------
/inst/images/sunset.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doehm/eyedroppeR/321d372fc2a866e3287a321118dfa27df50046e6/inst/images/sunset.png
--------------------------------------------------------------------------------
/man/choose_font_colour.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/helpers.R
3 | \name{choose_font_colour}
4 | \alias{choose_font_colour}
5 | \title{Choose font colour}
6 | \usage{
7 | choose_font_colour(bg, light = "#ffffff", dark = "#000000", threshold = 170)
8 | }
9 | \arguments{
10 | \item{bg}{Background}
11 |
12 | \item{light}{The light text colour}
13 |
14 | \item{dark}{The dark text colour}
15 |
16 | \item{threshold}{The threshold for switching}
17 | }
18 | \value{
19 | hex code
20 | }
21 | \description{
22 | Choose font colour
23 | }
24 |
--------------------------------------------------------------------------------
/man/extract_pal.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/eyedropper.R
3 | \name{extract_pal}
4 | \alias{extract_pal}
5 | \title{Extracts palette from an image}
6 | \usage{
7 | extract_pal(
8 | n,
9 | img_path,
10 | label = NULL,
11 | sort = "auto",
12 | plot_output = TRUE,
13 | save_output = FALSE,
14 | print_output = TRUE,
15 | swatch_radius = 50
16 | )
17 | }
18 | \arguments{
19 | \item{n}{Number of colours to extract}
20 |
21 | \item{img_path}{Path to image. If `NULL` the function will read from the clipboard}
22 |
23 | \item{label}{Label for the palette.}
24 |
25 | \item{sort}{Sort method. Either 'manual' or 'auto'}
26 |
27 | \item{plot_output}{logical. Default \code{TRUE}. Plots the output of the extracted palette.}
28 |
29 | \item{save_output}{logical. Default \code{FALSE}. Save the output of the extracted palette.}
30 |
31 | \item{print_output}{Print output to console to easily copy and paste into your script.}
32 |
33 | \item{swatch_radius}{Radius of the image for the swatch. Default 50 to make it a circle. Use 5 for rounded edges.}
34 | }
35 | \value{
36 | Returns a character vector of hex codes
37 | }
38 | \description{
39 | The image is read in using \code{magick}, converted to RGB and clustered using kmeans. The user
40 | must specify the number of clusters. The cluster centroids become the palette values.
41 | The function will ask the user to sort the palette values after clustering
42 | }
43 | \examples{
44 | path <- file.path(system.file(package = "eyedroppeR"), "images", "sunset.png")
45 |
46 | \dontrun{
47 | extract_pal(8, path)
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/man/eyedropper.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/eyedropper.R
3 | \name{eyedropper}
4 | \alias{eyedropper}
5 | \title{Eyedropper}
6 | \usage{
7 | eyedropper(
8 | n,
9 | img_path = NULL,
10 | label = NULL,
11 | inc_palette = TRUE,
12 | n_swatches = 24,
13 | print_output = TRUE,
14 | calibrate = FALSE,
15 | swatch_radius = 50,
16 | pixelate = FALSE
17 | )
18 | }
19 | \arguments{
20 | \item{n}{Number of colours to extract from the image}
21 |
22 | \item{img_path}{Path to image. Can be local or from a URL. If left \code{NULL},
23 | \code{eyedropper} will read the image address directly from the clipboard.}
24 |
25 | \item{label}{Label for the palette.}
26 |
27 | \item{inc_palette}{Logical. If \code{TRUE} it will automatically extract a palette
28 | first and then you can select the desired colours.}
29 |
30 | \item{n_swatches}{Number of swatches to extract from the image prior to selecting colours.}
31 |
32 | \item{print_output}{Print output to console to easily copy and paste into your script.}
33 |
34 | \item{calibrate}{Set to `TRUE` to calibrate the plot coordinates. Given the monitor
35 | resolution, scaling, etc it can throw off the pixel selection. Runs but default the first
36 | time the function is used.}
37 |
38 | \item{swatch_radius}{Radius of the image for the swatch. Default 50 to make it a circle. Use 5 for rounded edges.}
39 |
40 | \item{pixelate}{If `TRUE` or some numeric value, a low-res image will be displayed so that it is easier to select the right colour. Pixelate
41 | is set to `40` pixels. To make it more pixelated use a lower number of pixels e.g. `pixelate = 40`. If
42 | pixelate is used the palette selector at the bottom of the image won't be shown.}
43 | }
44 | \value{
45 | A character vector of hex codes
46 | }
47 | \description{
48 | Plots an image and allows the user to click on the image to
49 | return the hex of the pixel. Can select multiple colours at
50 | once by setting \code{n}.
51 | }
52 | \details{
53 | Use \code{eyedropper} with the following steps:
54 | \enumerate{
55 | \item{Find the image you want to pick colours from online.}
56 | \item{Right-click and 'copy image address'.}
57 | \item{Choose how many colours to pick e.g. \code{n = 5}.}
58 | \item{Run \code{pal <- eyedropper(n = 5, img_path = 'paste-image-path-here')}.}
59 | \item{Click 5 areas of the image. Thes image will be stretched to the borders of the window, but that's OK.}
60 | \item{Done! Copy the returned string / message and add it to you script and start using \code{pal}}
61 | }
62 |
63 | The first time the function is run it will initiate a calibration set. This is so the `y` coordinates are
64 | scaled properly as this can depend on the monitors resolution, scaling, etc. In only takes a couple of seconds
65 | and you only have to do it once.
66 |
67 | Make sure you click as near as practicable to the top and bottom of the border of the windew within the dot.
68 | }
69 | \examples{
70 | \dontrun{
71 |
72 | path <- file.path(system.file(package = "eyedroppeR"), "images", "hex.png")
73 |
74 | # Run eyedropper and click on 4 colours
75 | pal <- eyedropper(n = 4, path)
76 |
77 | pal
78 |
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/man/generate_palette.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/generate-palette.R
3 | \name{generate_palette}
4 | \alias{generate_palette}
5 | \title{Generate palette}
6 | \usage{
7 | generate_palette(n, prompt)
8 | }
9 | \arguments{
10 | \item{n}{Number of colours in the palette}
11 |
12 | \item{prompt}{Prompt}
13 | }
14 | \value{
15 | A vector of hex codes
16 | }
17 | \description{
18 | ⚠️ DEPRECATED: openai has been archived and I have to work out how to generate
19 | images with {ellmer} and the new APIs.
20 | }
21 | \examples{
22 | # x <- generate_palette(4, 'a trail in a dense rainforest')
23 | }
24 |
--------------------------------------------------------------------------------
/man/make_output.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/helpers.R
3 | \name{make_output}
4 | \alias{make_output}
5 | \title{Makes eyedroppers output}
6 | \usage{
7 | make_output(obj = NULL, pal, img_path)
8 | }
9 | \arguments{
10 | \item{obj}{Output from \code{extract_pal} or \code{eyedropper}}
11 |
12 | \item{pal}{Palette}
13 |
14 | \item{img_path}{Image path}
15 | }
16 | \value{
17 | ggplot object
18 | }
19 | \description{
20 | Plots the palette and places the image and label over the top.
21 | }
22 |
--------------------------------------------------------------------------------
/man/min_max.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/helpers.R
3 | \name{min_max}
4 | \alias{min_max}
5 | \title{Min-max scale function}
6 | \usage{
7 | min_max(x, a, b, a0 = NULL, b0 = NULL)
8 | }
9 | \arguments{
10 | \item{x}{Vector of values}
11 |
12 | \item{a}{Min}
13 |
14 | \item{b}{Max}
15 |
16 | \item{a0}{Min bound}
17 |
18 | \item{b0}{Max bound}
19 | }
20 | \value{
21 | numeric vector
22 | }
23 | \description{
24 | Min-max scale function
25 | }
26 |
--------------------------------------------------------------------------------
/man/modify_saturation.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/helpers.R
3 | \name{modify_saturation}
4 | \alias{modify_saturation}
5 | \title{Modify the saturation of a colour palette}
6 | \usage{
7 | modify_saturation(cols, sat = 1.2)
8 | }
9 | \arguments{
10 | \item{cols}{Vector of colours}
11 |
12 | \item{sat}{Factor to adjust the saturation}
13 | }
14 | \value{
15 | A vector of hex codes
16 | }
17 | \description{
18 | Modify the saturation of a colour palette
19 | }
20 |
--------------------------------------------------------------------------------
/man/palette.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/pencil-case.R
3 | \name{palette}
4 | \alias{palette}
5 | \title{Easily get a palette from the pencil case}
6 | \usage{
7 | palette(id)
8 | }
9 | \arguments{
10 | \item{id}{Number}
11 | }
12 | \value{
13 | A vector of hexcodes
14 | }
15 | \description{
16 | Easily get a palette from the pencil case
17 | }
18 | \examples{
19 | palette(1)
20 | }
21 |
--------------------------------------------------------------------------------
/man/paste_pal_code.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/helpers.R
3 | \name{paste_pal_code}
4 | \alias{paste_pal_code}
5 | \title{Copy + Pasteable palette vector}
6 | \usage{
7 | paste_pal_code(pal, label = NULL)
8 | }
9 | \arguments{
10 | \item{pal}{Palette vector}
11 |
12 | \item{label}{Label}
13 | }
14 | \value{
15 | a message
16 | }
17 | \description{
18 | Prints a message to console so you can easily copy and paste the palette
19 | }
20 |
--------------------------------------------------------------------------------
/man/pencil_case.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/pencil-case.R
3 | \docType{data}
4 | \name{pencil_case}
5 | \alias{pencil_case}
6 | \title{Pencil Case}
7 | \format{
8 | An object of class \code{list} of length 24.
9 | }
10 | \usage{
11 | pencil_case
12 | }
13 | \description{
14 | A list of palettes
15 | }
16 | \keyword{datasets}
17 |
--------------------------------------------------------------------------------
/man/show_pal.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/helpers.R
3 | \name{show_pal}
4 | \alias{show_pal}
5 | \title{Show palette}
6 | \usage{
7 | show_pal(pal)
8 | }
9 | \arguments{
10 | \item{pal}{Palette. Vector of hex codes}
11 | }
12 | \value{
13 | ggplot
14 | }
15 | \description{
16 | Plots the supplied palette for quick inspection
17 | }
18 | \examples{
19 | pal <- c('#57364e', '#566f1b', '#97a258', '#cac58b', '#dbedd5')
20 | show_pal(pal)
21 | }
22 |
--------------------------------------------------------------------------------
/man/show_pencil_case.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/pencil-case.R
3 | \name{show_pencil_case}
4 | \alias{show_pencil_case}
5 | \title{Shows all palettes in the pencil case}
6 | \usage{
7 | show_pencil_case(offset = 50)
8 | }
9 | \arguments{
10 | \item{offset}{Controls the overlapping circles}
11 | }
12 | \value{
13 | graphic of colour palettes
14 | }
15 | \description{
16 | Shows all palettes in the pencil case
17 | }
18 | \examples{
19 | show_pencil_case()
20 | }
21 |
--------------------------------------------------------------------------------
/man/sort_pal.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/helpers.R
3 | \name{sort_pal}
4 | \alias{sort_pal}
5 | \title{Manually sort a palette}
6 | \usage{
7 | sort_pal(pal, n = NULL, label = NULL, print_output = TRUE)
8 | }
9 | \arguments{
10 | \item{pal}{Palette. Character vector of hex codes}
11 |
12 | \item{n}{Number of colours to choose}
13 |
14 | \item{label}{Label for the palette.}
15 |
16 | \item{print_output}{Print output to console to easily copy and paste into your script.}
17 | }
18 | \value{
19 | Character vector
20 | }
21 | \description{
22 | The palette is displayed in the plotting window where you can click
23 | the colours in the order you want to sort them. The sorted palette
24 | will be returned. This saves you copy/pasting hex codes in your script.
25 | }
26 | \examples{
27 | \dontrun{
28 | pal <- sample(c('#57364e', '#566f1b', '#97a258', '#cac58b', '#dbedd5'))
29 | sort_pal(pal)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/man/sort_pal_auto.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/helpers.R
3 | \name{sort_pal_auto}
4 | \alias{sort_pal_auto}
5 | \title{Auto palette sort}
6 | \usage{
7 | sort_pal_auto(pal, label, plot_output = FALSE)
8 | }
9 | \arguments{
10 | \item{pal}{Input palette}
11 |
12 | \item{label}{Label for the palette.}
13 |
14 | \item{plot_output}{Logical. Default \code{FALSE}.}
15 | }
16 | \value{
17 | Returns a character vector of hex codes
18 | }
19 | \description{
20 | Automatically sorts the palette. May not give the desired result. If not you
21 | can run `sort_pal()` to manually sort.
22 | }
23 | \examples{
24 | pal <- sample(colours(), 8)
25 | sort_pal_auto(pal, 'test')
26 | }
27 |
--------------------------------------------------------------------------------
/man/swatch.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/helpers.R
3 | \name{swatch}
4 | \alias{swatch}
5 | \title{Swatch of colour palette}
6 | \usage{
7 | swatch(
8 | pal,
9 | img = NULL,
10 | label = NULL,
11 | padding = 0,
12 | radius = 20,
13 | ncols = 8,
14 | img_shadow = TRUE,
15 | shape = "original"
16 | )
17 | }
18 | \arguments{
19 | \item{pal}{Vector of colours}
20 |
21 | \item{img}{Image address. Either local file or URL}
22 |
23 | \item{label}{Label for the palette.}
24 |
25 | \item{padding}{To add whitespace to the top of image}
26 |
27 | \item{radius}{The radius of the feature image. Choose 50 for a circle, less then 50 for rounded square/rectangle.}
28 |
29 | \item{ncols}{Number of cols in a row}
30 |
31 | \item{img_shadow}{Logical. Apply a shadow to the feature image output.}
32 |
33 | \item{shape}{Either 'original' for the original image dimensions or "square"
34 | to crop to square with rounded corners. A high enough radius will turn the square to a circle.}
35 | }
36 | \value{
37 | html doc
38 | }
39 | \description{
40 | Swatch of colour palette
41 | }
42 | \examples{
43 | url <- "https://github.com/doehm/eyedroppeR/raw/main/dev/images/sunset-south-coast.jpg"
44 | x <- extract_pal(4, url)
45 | swatch(x$pal, url)
46 | }
47 |
--------------------------------------------------------------------------------