将 RasterBrick 数组保存为 *jpg 时,分割图像会丢失颜色

问题描述

#Packages
library(raster)  
library(rgeos)
library(rgdal)
library(jpeg)

我有一个 RGB 颜色 *jpg 图像:

## Open my RGB image 
 path<-"https://raw.githubusercontent.com/Leprechault/trash/main/IMG_191022_134242_0000_RGB.JPG" # Image path
download.file(path,"IMG_191022_134242_0000_RGB.JPG",mode = "wb")
rc<-stack(raster("IMG_191022_134242_0000_RGB.JPG")) #Open as a raster and stack
plot(rc)

bigimage

当我尝试分割成 16 张相同大小的图像时:

# This function spatially aggregates the original raster
# it turns each aggregated cell into a polygon
# then the extent of each polygon is used to crop
# the original raster.
# The function returns a list with all the pieces
# it saves and plots each piece
# The arguments are:
# raster = raster to be chopped            (raster object)
# ppside = pieces per side                 (integer)
# save   = write raster                    (TRUE or FALSE)
# plot   = do you want to plot the output? (TRUE or FALSE)
SplitRas <- function(raster,ppside,save,plot){
  h        <- ceiling(ncol(raster)/ppside)
  v        <- ceiling(nrow(raster)/ppside)
  agg      <- aggregate(raster,fact=c(h,v))
  agg[]    <- 1:ncell(agg)
  agg_poly <- rasterTopolygons(agg)
  names(agg_poly) <- "polis"
  r_list <- list()
  for(i in 1:ncell(agg)){
    e1          <- extent(agg_poly[agg_poly$polis==i,])
    r_list[[i]] <- crop(raster,e1)
  }
  if(save==T){
    for(i in 1:length(r_list)){
      options(max.print=999999) 
      #EBImage::writeImage(as.array(r_list[[i]]/255),paste0("sample_",i,".jpg",sep=""),quality = 100)
      writeJPEG(as.array(r_list[[i]]/255),target = paste0("sample_",quality = 1,color.space="RGBA")
    }
  }
  return(r_list)
}

#Slip RGB raster in 16 subimages
splitRBG<-SplitRas(raster=rc,ppside=4,save=TRUE)
# 

结果是灰度图像,例如。 16 个图像中的 1 个 (sample_1.jpg):

enter image description here

我尝试对 writeJPEG() 函数进行大量更改(as.array(r_list[[i]]/255) 代码color.space 中存在错误)但没有成功,请问有什么想法吗?

解决方法

解决方案:使用raster自定义函数在裁剪操作之前将每个RGB通道拆分为单独的rst.blue,rst.green nad rst.red层(stack)和SplitRas

#Packages
library(raster)  
library(rgeos)
library(rgdal)
library(jpeg)

## download RGB image 
path<-"https://raw.githubusercontent.com/Leprechault/trash/main/IMG_191022_134242_0000_RGB.JPG" # Image path
download.file(path,"IMG_191022_134242_0000_RGB.JPG",mode = "wb")

# Open jpeg file
jpg<-readJPEG("IMG_191022_134242_0000_RGB.JPG")

# Convert imagedata to raster
rst.blue <- raster(jpg[,1])
rst.green <- raster(jpg[,2])
rst.red <- raster(jpg[,3])
rc<-stack(rst.blue,rst.green,rst.red)


# This function spatially aggregates the original raster
# it turns each aggregated cell into a polygon
# then the extent of each polygon is used to crop
# the original raster.
# The function returns a list with all the pieces
# it saves and plots each piece
# The arguments are:
# raster = raster to be chopped            (raster object)
# ppside = pieces per side                 (integer)
# save   = write raster                    (TRUE or FALSE)
# plot   = do you want to plot the output? (TRUE or FALSE)
SplitRas <- function(raster,ppside,save,plot){
  h        <- ceiling(ncol(raster)/ppside)
  v        <- ceiling(nrow(raster)/ppside)
  agg      <- aggregate(raster,fact=c(h,v))
  agg[]    <- 1:ncell(agg)
  agg_poly <- rasterToPolygons(agg)
  names(agg_poly) <- "polis"
  r_list <- list()
  for(i in 1:ncell(agg)){
    e1          <- extent(agg_poly[agg_poly$polis==i,])
    r_list[[i]] <- crop(raster,e1)
  }
  if(save==T){
    for(i in 1:length(r_list)){
      writeJPEG(as.array(r_list[[i]]),target = paste0("sample_",i,".jpg",sep=""),quality = 1)
    }
  }
  return(r_list)
}

#Slip RGB raster in 4 equal parts
splitRBG<-SplitRas(raster=rc,ppside=4,save=TRUE)
#