6

我正在尝试使用 R 从数据矩阵创建光栅图像。但是,我的图像边缘出现了一些奇怪的伪影。

我正在使用的代码如下:

# From the example for rasterImage(). A 3 pixel by 5 pixel b/w checkerboard.
testImage <- as.raster(0:1, nrow=3, ncol=5)

testImage
     [,1]      [,2]      [,3]      [,4]      [,5]     
[1,] "#000000" "#FFFFFF" "#000000" "#FFFFFF" "#000000"
[2,] "#FFFFFF" "#000000" "#FFFFFF" "#000000" "#FFFFFF"
[3,] "#000000" "#FFFFFF" "#000000" "#FFFFFF" "#000000"

png('test.png', width=5, height=3, units='px')

# Just want the image, no margins, boarders or other fancy stuff.
par(mar = c(0,0,0,0) )
plot.new()
plotArea = par('fig')

rasterImage(testImage, plotArea[1], plotArea[3],
  plotArea[2], plotArea[4], interpolate = FALSE )

dev.off()

这是在 OS X 上的 R 2.12.0 中执行的,但我从 R 2.11.0 得到相同的输出。


我得到的输出如下(从 5x3 缩放到 150x90)

R输出

角落的像素应该是黑色的,这表明正在发生某种形式的插值。


我期望看到的输出是:

预期产出

关于为什么我的代码无法忠实地从矩阵生成光栅图像的任何建议?


有可能的使用

这是针对我正在开发的一个包,所以如果可能的话,我想留在 R 基础包中,以免引入额外的依赖项。该包实现了一个图形设备,所以如果有人有一个 C 级解决方案从传入的信息GERaster()src/main/engine.c提取并仅使用 R 库创建一个 PNG,我也愿意试一试。


OS X 解决方案

正如 nico 所指出的,错误行为是抗锯齿的结果。png()如果被告知使用可以禁用抗锯齿的输出方法(例如 Cairo 图形),则该图的行为与预期一致:

png('test.png', width=5, height=3, units='px', type='cairo', antialias=NULL)

在 OS X 上,默认后端png()是 Quartz,但png(..., type='quartz')目前忽略quartz.options(). quartz()如果设备通过直接调用而不是使用来启动,则可以在 OS X 上本地生成忠实输出png()

quartz(file='test.png', type='png', width=5, height=3, dpi=1, antialias=FALSE)

Windows 有不同的想法

在 Windows 上生成以下输出:

窗口输出

根据Paul Murrell(R 图形设备的仁慈独裁者)在 R-help 邮件列表中给出的答案:

这是一个舍入(截断)问题。正在修复。

除非光栅图像包含非常少的像素,否则 Windows 上的这种行为应该不会引起注意。

4

2 回答 2

1

您的代码按我的预期工作......(在 Fedora Core 13 下运行的 R 2.11.1)。这似乎是一个抗锯齿问题

这段代码可以解决问题

png('test.png', width=5, height=3, units='px', type='cairo', antialias=NULL)

默认的抗锯齿选项可以在X11.options

?X11.options

antialias: for cairo types, the type of anti-aliasing (if any) to be
      used.  One of ‘c("default", "none", "gray", "subpixel")’.
于 2010-10-18T06:44:15.853 回答
1

你听说过raster包裹吗?也许它可能有一些服务。

library(raster)
test.image <- matrix(c(1, 0, 1, 0, 0, 1, 0, 1), ncol = 4, byrow = TRUE)
plot(raster(test.image))

png("test.png")
image(test.image, axes = FALSE)
dev.off()
于 2010-10-18T07:14:02.723 回答