「r」事實(shí)不等于標(biāo)簽:關(guān)于真假 png 的找 bug 記錄

這是針對(duì)今天找 bug 的記錄丰捷。


我在日常更改 sigminer 手冊(cè)后使用 knitr 生成網(wǎng)頁(yè)文檔時(shí)發(fā)現(xiàn)一直報(bào)錯(cuò):

Quitting from lines 42-43 (sigminer-doc.Rmd) 
Error in png::readPNG(path, native = TRUE, info = TRUE) : 
  file is not in PNG format

這個(gè)報(bào)錯(cuò)源自于我使用了 knitr::include_graphics() 插入 png 圖片病往。圖片來(lái)自一篇自然綜述停巷,用于介紹 Mutation Signatures。

之前我也遇到過(guò)這種報(bào)錯(cuò),后來(lái)莫名其妙好了庆揪,我也就沒(méi)管了。今天不知道為什么又出現(xiàn)這種情況吝羞,所以還是自動(dòng)動(dòng)手想辦法解決吧钧排。

在 RStudio 的 code chunk 運(yùn)行中均澳,我是能正常看到預(yù)覽的圖片的糟袁,按理來(lái)說(shuō)沒(méi)有問(wèn)題系吭。我又試著使用 png::readPNG() 直接在控制臺(tái)讀入一張 png 圖片(這是一個(gè)重點(diǎn))肯尺,出現(xiàn)了跟報(bào)錯(cuò)無(wú)關(guān)的警告,但能夠正常讀入槐臀。這就奇怪了水慨。敬扛。啥箭。

我試著使用 debug() 函數(shù)后再運(yùn)行 knit,這樣可以跳入報(bào)錯(cuò)代碼急侥,按逐步運(yùn)行確實(shí)有出現(xiàn)了上述的報(bào)錯(cuò)贝润!

我依稀想起來(lái)之前重裝 knitr 包好像解決了問(wèn)題铝宵,我又重裝 knitr,還是報(bào)錯(cuò)胧卤。

面對(duì)這個(gè)重復(fù)的報(bào)錯(cuò)拼岳,我越想越偏惜纸,我看到 png 包在讀入數(shù)據(jù)時(shí)底層應(yīng)該是調(diào)用了 C(++) 代碼耐版,難道是 png 包問(wèn)題粪牲?我重裝它還是沒(méi)解決,我又試著安裝源碼包落君,還是有問(wèn)題绎速。纹冤。。

真是奇怪购公,不可能存在兩份代碼萌京,我 knitr 外不報(bào)錯(cuò),而在 knitr 使用時(shí)報(bào)錯(cuò)宏浩。想不明白的我暫時(shí)把問(wèn)題扔到了 Stack overflow https://stackoverflow.com/questions/61721837/cannot-use-include-graphics-to-insert-png-in-rmarkdown-error-file-is-not-in-pn枫夺,吃飯去吧。

吃飯回來(lái)休息后打開(kāi)一開(kāi)發(fā)現(xiàn)有一回答:

I think that the issue might be where your Rmd is located

這個(gè)回答我內(nèi)心覺(jué)得不對(duì)绘闷,因?yàn)槲乙恢笔窃?Rmd 所在目錄進(jìn)行 knit 的橡庞,之前我使用 knitr 也沒(méi)遇到這方面問(wèn)題。不過(guò)如果真是這樣呢印蔗?還是試試吧扒最。

緊接著問(wèn)題來(lái)了,我發(fā)現(xiàn)在 knit 的過(guò)程中我是無(wú)法在控制臺(tái)看到輸出的华嘹!這該怎么辦呢吧趣?强挫?搜解決辦法。

通過(guò)谷歌我找到 2 種比較靠譜的方法來(lái)查看 knit 時(shí)使用的根目錄絮爷。

第一種是根據(jù) knitr 進(jìn)行設(shè)定:

knitr::opts_knit$set(root.dir = rprojroot::find_rstudio_root_file())

這樣就把 knit 時(shí)候的根目錄跟 RStudio 使用的根目錄保持一致了。但還是報(bào)錯(cuò),而且這里我無(wú)法查看到底根目錄是什么跨释。

第二種方法的來(lái)源鏈接我忘了阔涉,是在 Stack overflow 上贯要,我做了一點(diǎn)小的修改:

knitr::knit_hooks$set(debug = function(before, options, envir) {
  if (!before) {
    envir = as.list(envir)
    message("Objects: ", paste(names(envir), collapse = " "))
    for (i in names(envir)) {
      if (!startsWith(i, ".")) {
        message(
          i, " = ", envir[[i]]
        )
      }
    }
  }
})

加入這段代碼后我就可以在 code chunk 的設(shè)定中加 debug = TRUE,然后將 rprojroot::find_rstudio_root_file()getwd() 的結(jié)果賦值給變量跟狱,knit 的時(shí)候會(huì)提示變量信息叼丑。

Objects: workdir root.dir
workdir = /Users/wsx/Documents/GitHub/sigminer-doc
root.dir = /Users/wsx/Documents/GitHub/sigminer-doc
  |.....                                                                                                                                 |   4%
  ordinary text without R code

  |......                                                                                                                                |   5%
label: unnamed-chunk-3 (with options) 
List of 2
 $ echo   : logi FALSE
 $ fig.cap: chr "The illustration of SBS signature, fig source: https://www.nature.com/articles/nrg3729"

Quitting from lines 64-65 (sigminer-doc.Rmd) 
Error in png::readPNG(path, native = TRUE, info = TRUE) : 
  file is not in PNG format

從輸出來(lái)看 Rmd 的工作目錄是完全沒(méi)有問(wèn)題的店雅。那問(wèn)題到底在哪里呢闹啦?酱畅?看著 file is not in PNG format 這個(gè)錯(cuò)誤提示,我久久不能釋?xiě)阉槲桑€是要搞掉它。

目前我在這個(gè)文檔中我引入了外部 3 張 png 圖片,我一個(gè)一個(gè)讀取試試。

我 Ca,怎么有失敗的。

> png::readPNG("fig/sbs_signature_overview.png")
 [ reached getOption("max.print") -- omitted 3 matrix slice(s) ]
Warning message:
In png::readPNG("fig/sbs_signature_overview.png") :
  libpng warning: iCCP: known incorrect sRGB profile
> png::readPNG("fig/sbs_signature_overview_nat_review.png")
Error in png::readPNG("fig/sbs_signature_overview_nat_review.png") : 
  file is not in PNG format

恍然大悟,之前我讀取正常的并不是我 knit 引起報(bào)錯(cuò)的。因?yàn)樗鼈兌际?png 文件扯俱,所以我覺(jué)得沒(méi)什么不同晴玖,也就沒(méi)有額外注意

既然格式不對(duì)尔当,那就得想辦法知道報(bào)錯(cuò)圖片的格式侠碧。我試了下 jpeg::readJPEG()瓷式,發(fā)現(xiàn)還是報(bào)錯(cuò)。這樣搞不行妒挎,鬼知道有多少種圖片格式鳞芙,得找個(gè)工具喳坠。

接著我找到了正確的工具 magick御板。

一查,報(bào)錯(cuò)圖片還真不是 png 格式:

> error_file = magick::image_read("fig/sbs_signature_overview_nat_review.png")
> print(error_file)
  format width height colorspace matte filesize density
1   WEBP   685    521       sRGB FALSE    18390   72x72

原來(lái)我以為網(wǎng)絡(luò)圖片另存為 .png 就成了 png 圖片惶楼。。铝穷。镊尺。

最后還是通過(guò)這個(gè)工具轉(zhuǎn)換生成一張 png 格式的,從根本上解決了問(wèn)題:

> right_png <- magick::image_convert(error_file, "png")
> right_png
  format width height colorspace matte filesize density
1    PNG   685    521       sRGB FALSE        0   72x72
> magick::image_write(right_png, path = "fig/sbs_signature_overview_nat_review2.png", format = "png")

那么問(wèn)題又來(lái)了衣式,為什么使用在 RStudio 中使用 knitr::include_graphics() 預(yù)覽是正常的呢?在寫(xiě)到這里的時(shí)候瓮具,我突然想到預(yù)覽時(shí) knitr 應(yīng)該不是調(diào)用的 png 進(jìn)行讀取搭综,所以沒(méi)有報(bào)錯(cuò)条获。

現(xiàn)在回想起來(lái)有點(diǎn)想罵自己沒(méi)腦子帅掘,有兩個(gè)點(diǎn)如果注意了吱窝,我不會(huì)花這么多時(shí)間:

  • 測(cè)試 png 讀取時(shí)應(yīng)該使用報(bào)錯(cuò)的圖片照激。
  • 認(rèn)真理解報(bào)錯(cuò)信息六水。

但作為一個(gè)人,往往難以客觀準(zhǔn)確高效地看清問(wèn)題本質(zhì)咧欣。另一方面說(shuō),沒(méi)有愚蠢的操作轨帜,我也不會(huì)想盡辦法各種深挖魄咕,事后寫(xiě)篇文章記錄下了。

程序不會(huì)錯(cuò)蚌父,錯(cuò)的是我們的思維哮兰;bug 不可怕,可怕的它生出一堆 bugs(剛好看到 Y 叔今日推文)苟弛。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末喝滞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子膏秫,更是在濱河造成了極大的恐慌右遭,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,888評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異窘哈,居然都是意外死亡言蛇,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)宵距,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)腊尚,“玉大人,你說(shuō)我怎么就攤上這事满哪⌒龀猓” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,386評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵哨鸭,是天一觀的道長(zhǎng)民宿。 經(jīng)常有香客問(wèn)我,道長(zhǎng)像鸡,這世上最難降的妖魔是什么活鹰? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,726評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮只估,結(jié)果婚禮上志群,老公的妹妹穿的比我還像新娘。我一直安慰自己蛔钙,他們只是感情好锌云,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著吁脱,像睡著了一般桑涎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上兼贡,一...
    開(kāi)封第一講書(shū)人閱讀 52,337評(píng)論 1 310
  • 那天攻冷,我揣著相機(jī)與錄音,去河邊找鬼遍希。 笑死等曼,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的孵班。 我是一名探鬼主播涉兽,決...
    沈念sama閱讀 40,902評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼篙程!你這毒婦竟也來(lái)了枷畏?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,807評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤虱饿,失蹤者是張志新(化名)和其女友劉穎拥诡,沒(méi)想到半個(gè)月后触趴,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,349評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡渴肉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評(píng)論 3 340
  • 正文 我和宋清朗相戀三年冗懦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仇祭。...
    茶點(diǎn)故事閱讀 40,567評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡披蕉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出乌奇,到底是詐尸還是另有隱情没讲,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評(píng)論 5 350
  • 正文 年R本政府宣布礁苗,位于F島的核電站爬凑,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏试伙。R本人自食惡果不足惜嘁信,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疏叨。 院中可真熱鬧潘靖,春花似錦、人聲如沸考廉。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,420評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)昌粤。三九已至,卻和暖如春啄刹,著一層夾襖步出監(jiān)牢的瞬間涮坐,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,531評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工誓军, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留袱讹,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,995評(píng)論 3 377
  • 正文 我出身青樓昵时,卻偏偏與公主長(zhǎng)得像捷雕,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子壹甥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評(píng)論 2 359