Use PreviewPageTextExtractor to convert every pdf page into image and OCR after

conversion. Also decouple OCR logic from FetchPageContent.
This commit is contained in:
Anthony Tseng
2024-04-12 11:55:45 -07:00
parent d2c55fa804
commit cf0853f624
17 changed files with 266 additions and 218 deletions
+48 -48
View File
@@ -5,8 +5,8 @@
#include "brave/services/printing/pdf_to_bitmap_converter.h"
#include <optional>
#include <utility>
#include <vector>
#include "base/logging.h"
#include "base/memory/shared_memory_mapping.h"
@@ -20,70 +20,70 @@ PdfToBitmapConverter::PdfToBitmapConverter() = default;
PdfToBitmapConverter::~PdfToBitmapConverter() = default;
void PdfToBitmapConverter::GetBitmap(
void PdfToBitmapConverter::GetPdfPageCount(
base::ReadOnlySharedMemoryRegion pdf_region,
std::optional<uint8_t> max_pages,
GetBitmapCallback callback) {
// Decode memory region as PDF bytes.
GetPdfPageCountCallback callback) {
base::ReadOnlySharedMemoryMapping pdf_map = pdf_region.Map();
if (!pdf_map.IsValid()) {
DLOG(ERROR) << "Failed to decode memory map for PDF thumbnail";
DLOG(ERROR) << "Failed to decode memory map for PDF";
std::move(callback).Run(std::nullopt);
return;
}
auto pdf_buffer = pdf_map.GetMemoryAsSpan<const uint8_t>();
int page_count;
if (!chrome_pdf::GetPDFDocInfo(pdf_buffer, &page_count, nullptr)) {
DLOG(ERROR) << "Failed to get PDF document info";
std::move(callback).Run(std::nullopt);
return;
}
std::move(callback).Run(page_count);
}
if (max_pages.has_value() && *max_pages < page_count) {
page_count = *max_pages;
void PdfToBitmapConverter::GetBitmap(
base::ReadOnlySharedMemoryRegion pdf_region,
uint32_t page_index,
GetBitmapCallback callback) {
base::ReadOnlySharedMemoryMapping pdf_map = pdf_region.Map();
if (!pdf_map.IsValid()) {
DLOG(ERROR) << "Failed to decode memory map for PDF";
std::move(callback).Run(SkBitmap());
}
auto pdf_buffer = pdf_map.GetMemoryAsSpan<const uint8_t>();
std::optional<gfx::SizeF> page_size =
chrome_pdf::GetPDFPageSizeByIndex(pdf_buffer, page_index);
if (!page_size.has_value()) {
DLOG(ERROR) << "Failed to get PDF page size";
std::move(callback).Run(SkBitmap());
return;
}
gfx::Size size = gfx::ToCeiledSize(*page_size);
SkBitmap bitmap;
const SkImageInfo info = SkImageInfo::Make(
size.width(), size.height(), kBGRA_8888_SkColorType, kOpaque_SkAlphaType);
if (!bitmap.tryAllocPixels(info, info.minRowBytes())) {
DLOG(ERROR) << "Failed to allocate bitmap pixels";
std::move(callback).Run(SkBitmap());
return;
}
std::vector<SkBitmap> bitmaps;
for (int page_index = 0; page_index < page_count; page_index++) {
std::optional<gfx::SizeF> page_size =
chrome_pdf::GetPDFPageSizeByIndex(pdf_buffer, page_index);
if (!page_size.has_value()) {
DLOG(ERROR) << "Failed to get PDF page size";
std::move(callback).Run(std::nullopt);
return;
}
gfx::Size size = gfx::ToCeiledSize(*page_size);
SkBitmap bitmap;
const SkImageInfo info =
SkImageInfo::Make(size.width(), size.height(), kBGRA_8888_SkColorType,
kOpaque_SkAlphaType);
if (!bitmap.tryAllocPixels(info, info.minRowBytes())) {
DLOG(ERROR) << "Failed to allocate bitmap pixels";
std::move(callback).Run(std::nullopt);
return;
}
// Convert PDF bytes into a bitmap
chrome_pdf::RenderOptions options = {
.stretch_to_bounds = false,
.keep_aspect_ratio = true,
.autorotate = false,
.use_color = true,
.render_device_type = chrome_pdf::RenderDeviceType::kDisplay,
};
if (!chrome_pdf::RenderPDFPageToBitmap(pdf_buffer, page_index,
bitmap.getPixels(), size,
gfx::Size(300, 300), options)) {
DLOG(ERROR) << "Failed to render PDF buffer as bitmap image";
std::move(callback).Run(std::nullopt);
return;
}
bitmaps.push_back(bitmap);
// Convert PDF bytes into a bitmap
chrome_pdf::RenderOptions options = {
.stretch_to_bounds = false,
.keep_aspect_ratio = true,
.autorotate = false,
.use_color = true,
.render_device_type = chrome_pdf::RenderDeviceType::kDisplay,
};
if (!chrome_pdf::RenderPDFPageToBitmap(pdf_buffer, page_index,
bitmap.getPixels(), size,
gfx::Size(300, 300), options)) {
DLOG(ERROR) << "Failed to render PDF buffer as bitmap image";
std::move(callback).Run(SkBitmap());
return;
}
std::move(callback).Run(bitmaps);
std::move(callback).Run(std::move(bitmap));
}
void PdfToBitmapConverter::SetUseSkiaRendererPolicy(bool use_skia) {
+3 -1
View File
@@ -22,8 +22,10 @@ class PdfToBitmapConverter : public printing::mojom::PdfToBitmapConverter {
PdfToBitmapConverter& operator=(const PdfToBitmapConverter&) = delete;
// printing::mojom::PdfToBitmapConverter:
void GetPdfPageCount(base::ReadOnlySharedMemoryRegion pdf_region,
GetPdfPageCountCallback callback) override;
void GetBitmap(base::ReadOnlySharedMemoryRegion pdf_region,
std::optional<uint8_t> max_pages,
uint32_t page_index,
GetBitmapCallback callback) override;
void SetUseSkiaRendererPolicy(bool use_skia) override;
@@ -10,9 +10,11 @@ import "skia/public/mojom/bitmap.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom";
interface PdfToBitmapConverter {
// If max_pages is provided, the converter will process at most max_pages
GetPdfPageCount(mojo_base.mojom.ReadOnlySharedMemoryRegion pdf_region)
=> (uint32? page_count);
GetBitmap(mojo_base.mojom.ReadOnlySharedMemoryRegion pdf_region,
uint8? max_pages) => (array<skia.mojom.BitmapN32>? bitmap);
uint32 page_index) => (skia.mojom.BitmapN32? bitmap);
// Sets the status for enterprise policy `kPdfUseSkiaRendererEnabled`. It
// should be called immediately once `mojom::PdfToBitmapConverter` remote