用R从PDF文件中提取字符字体大小

用R从PDF文件中提取字符字体大小,r,pdf,text-mining,R,Pdf,Text Mining,我一直在试图复制一个类似的数据集(我强调,不完全相同),在本文中解释了类似的目的。但是我很难想出一个在R中编码时获得字体大小的方法。其他的解决方案似乎也可以在其他的编码语言中使用 例如,我们可以很容易地提取关于页面中字符数的信息,或者转换图像中的每一页,并获取关于像素数等的数据,这将是我的元数据的一部分。例如,在下面的示例中: library(pdftools) library(png) download.file("http://arxiv.org/pdf/1403.2805.pdf", "

我一直在试图复制一个类似的数据集(我强调,不完全相同),在本文中解释了类似的目的。但是我很难想出一个在R中编码时获得字体大小的方法。其他的解决方案似乎也可以在其他的编码语言中使用

例如,我们可以很容易地提取关于页面中字符数的信息,或者转换图像中的每一页,并获取关于像素数等的数据,这将是我的元数据的一部分。例如,在下面的示例中:

library(pdftools)
library(png)

download.file("http://arxiv.org/pdf/1403.2805.pdf", "1403.2805.pdf", mode = "wb")

txt <- pdf_text("1403.2805.pdf")

num_char_page = unlist(lapply(txt,nchar))

height = 1:length(txt)
width =1:length(txt)

for (i in 1:length(txt)) {

  bitmap <- pdf_render_page("1403.2805.pdf", page = i)

  png::writePNG(bitmap, paste0("page",i,".png"))

  photo=readPNG(paste0("page",i,".png"))

  height[i]  = dim(photo)[1]

  width[i] = dim(photo)[2]

}

layout_df = data.frame(page=1:length(txt), num_char_page=num_char_page, height=height, width=width)
库(pdftools)
图书馆(png)
下载文件(“http://arxiv.org/pdf/1403.2805.pdf“,”1403.2805.pdf“,mode=“wb”)

txt可能无法确定实际字体大小,至少在不知道确切字体及其规格的情况下是不可能的

如果您只想比较文档之间的字体大小,那么使用平均行高作为比较就足够了,这可能更容易做到。如果您不关心实际值,只需要知道文档之间的相对大小,那么以下方法可能有效。您必须考虑或避免不同文档大小和/或DPI的潜在影响。

library(tesseract)
library(dplyr)
library(tidyr)

df <- ocr_data("http://arxiv.org/pdf/1403.2805.pdf")

df %>% 
  separate(bbox, c('x1', 'y1', 'x2', 'y2'), convert = T) %>% 
  mutate(line_height = y2 - y1) %>% 
  summarise(avg_line_height = mean(line_height))

# # A tibble: 1 x 1
#   avg_line_height
#             <dbl>
# 1            58.7

在png::writePNG语句中,是否需要另一个右括号?是的,已经编辑过了。我正在尝试对律师事务所发布的PDF格式的调查报告进行类似的分析。我们可以就各自的研究和工具进行聊天或发电子邮件吗?是的,当然可以。太好了,我如何联系到你或你如何联系到我?是否有其他方法来构建宽度?如果我用面积(宽x高)和每行字符数(类似于字符数除以面积的平均值)构造一个平均值,我可能会得到足够接近字符字体大小的值。tesseract返回每个单词的边界框,因此,您可以使用/num\u of_chars=avg\u letter\u width来计算单词。参见上面的新示例,我认为
ocr\u data
函数没有那么好地工作。第3页、第4页、第5页、第6页和第7页(以及其他页)不生成TIBLE。你认为我们在这方面有其他选择吗?也许可以将png文件转换为更高的分辨率。我会试试的。tesseract是我所知道的最古老、最好的OCR系统之一。使用上面的示例代码,所有页面都成功地进行了OCR,数据帧被创建和合并。可能您的机器上发生了其他错误。
df %>%
  separate(bbox, c('x1', 'y1', 'x2', 'y2'), convert = T) %>%
  mutate(word_height = y2 - y1) %>%
  mutate(word_width = x2 - x1) %>%
  mutate(num_letters = nchar(word)) %>%
  mutate(avg_letter_width = word_width / num_letters) %>%
  summarise(avg_letter_height = mean(word_height),
            avg_letter_width = mean(avg_letter_width))

# # A tibble: 1 x 2
#   avg_letter_height avg_letter_width
#               <dbl>            <dbl>
# 1              58.7             37.3
library(pdftools)
library(tesseract)
library(dplyr)
library(tidyr)

download.file(url = "http://arxiv.org/pdf/1403.2805.pdf",
              destfile = pdf_path <- tempfile(fileext = ".pdf"))

page_pngs <-
  lapply(seq_len(pdf_info(pdf_path)$pages), function(page_num) {
    pdf_convert(pdf_path, pages = page_num, dpi = 300)
  })

df <-
  bind_rows(
    lapply(seq_len(length(page_pngs)), function(page_num) {
      ocr_data(page_pngs[[page_num]]) %>%
        separate(bbox, c('x1', 'y1', 'x2', 'y2'), convert = T) %>%
        mutate(word_height = y2 - y1) %>%
        mutate(word_width = x2 - x1) %>%
        mutate(num_letters = nchar(word)) %>%
        mutate(avg_letter_width = word_width / num_letters) %>%
        mutate(page = page_num) %>%
        select(page, letter_height = word_height, letter_width = avg_letter_width)
    })
  )

df %>%
  group_by(page) %>%
  summarise(avg_letter_height = mean(letter_height),
            avg_letter_width = mean(letter_width)) %>%
  mutate(avg_letter_area = avg_letter_height * avg_letter_width)

# # A tibble: 29 x 4
#     page avg_letter_height avg_letter_width avg_letter_area
#    <int>             <dbl>            <dbl>           <dbl>
#  1     1              29.4             17.9            525.
#  2     2              29.3             18.9            554.
#  3     3              30.0             19.1            574.
#  4     4              30.2             18.7            565.
#  5     5              29.8             19.0            566.
#  6     6              28.2             17.7            498.
#  7     7              28.9             18.3            529.
#  8     8              29.8             18.6            554.
#  9     9              29.1             18.6            541.
# 10    10              28.3             18.3            519.
# # ... with 19 more rows