민프
[Android] 여러 페이지의 PDF 로 만들어보자(PdfDocument, Paint, Canvas, 레이아웃 캡쳐) 본문
현재 여행 다이어리 관련 어플을 만들고 있는데
내가 만든 여행기의 여행 루트, 사진, 메모 등을 여행 루트당 정보를 한 페이지의 PDF로 만들어 보려고 한다.
사용되는 주요 클래스로는
PdfDocument, Canvas , Paint이다.
내가 생각한 진행으로는 2가지가 있다.
1. 여행기 루트 정보 -> 레이아웃에 정보 넣기 -> 레이아웃을 Bitmap으로 캡쳐 -> Bitmap을 Canvas에 넣고 -> PDF로 생성 (계단현상 발생)
2. 여행기 루트 정보 -> 텍스트는 canvas.drawText, 이미지는 canvas.drawBitmap 으로 그려주기 -> PDF 생성
(Text MulitLine 문제 => StaticLayout으로 해결)
* 1번 방법에 대한 문제점: 캡쳐를 하는 것 이기 때문에 확대, 축소를 할 때 텍스트, 이미지의 계단 현상이 보이게 된다. 따라서 Capture을 하지 말고 Pdf에 직접적으로 텍스트를 넣어 보기로 했다. |
* 2번 방법의 문제점: 밑 사진에서 보는 것 처럼 글자가 확대를 해도 깨지지는 않지만 Text의 Mulit라인 문제였다. 근데 이 부분은 StaticLayout으로 MutiLine 구현이 가능하다고 하니 이 방법을 해보기로 하였다. (StaticLayout은 처음..들어보는 것으로.. 새롭게 포스트를 써봐야겠다..) https://minf.tistory.com/3 |
PdfDocument 이 클래스는 네이티브 Android 콘텐츠에서 PDF 문서를 생성 할 수 있도록합니다. 새 문서를 만든 다음 추가하려는 모든 페이지에 대해 페이지를 시작하고 페이지에 콘텐츠를 작성한 다음 페이지를 완료합니다. 모든 페이지를 완료 한 후 문서를 출력 스트림에 쓰고 문서를 닫습니다. 문서를 닫은 후에는 더 이상 사용하지 마십시오. 페이지는 하나씩 작성됩니다. 즉, 주어진 시간에 작성중인 단일 페이지 만 가질 수 있습니다. 이 클래스는 스레드로부터 안전하지 않습니다. API의 일반적인 사용은 다음과 같습니다. // create a new document PdfDocument document = new PdfDocument(); // create a page description PageInfo pageInfo = new PageInfo.Builder(100, 100, 1).create(); // start a page Page page = document.startPage(pageInfo); // draw something on the page View content = getContentView(); content.draw(page.getCanvas()); // finish the page document.finishPage(page); . . . // add more pages . . . // write the document content document.writeTo(getOutputStream()); // close the document document.close(); https://developer.android.com/reference/android/graphics/pdf/PdfDocument PdfDocument.PageInfo.Builderhttps://developer.android.com/reference/android/graphics/pdf/PdfDocument.PageInfo.Builder |
Canvas Canvas 클래스는 "draw"호출을 보유합니다. 무언가를 그리려면 4 개의 기본 구성 요소가 필요합니다. 픽셀을 보관할 비트 맵, 드로 콜 (비트 맵에 쓰기)을 호스팅하는 캔버스, 그리기 기본 (예 : 사각형, 경로, 텍스트, 비트 맵) 및 페인트 ( 그림의 색상과 스타일을 설명하십시오). https://developer.android.com/reference/android/graphics/Canvas |
Paint Paint 클래스에는 도형, 텍스트 및 비트 맵을 그리는 방법에 대한 스타일 및 색상 정보가 있습니다. https://developer.android.com/reference/android/graphics/Paint |
쉽게 생각해보면
Canvas는 뜻 그대로 도화지라고 생각하고
Paint는 그 위에 그릴 수 있게 하는 것 이다.
PdfDocument pdfDocument = new PdfDocument(); // Android 콘텐츠에서 PDF 문서를 생성 할 수 있도록 하는 클래스
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(595,842,1).create();
PdfDocument.Page page = pdfDocument.startPage(pageInfo);
Canvas canvas = page.getCanvas(); // 캔버스 도화지 생성
Paint root_image_paint = new Paint();
pdf_root_img.buildDrawingCache();//캐쉬 저장
Bitmap capture_bitmap = pdf_root_img.getDrawingCache();
Bitmap resize_capture_bitmap = resizeBitmapImageFn(capture_bitmap,400);
root_image_paint.setAntiAlias(true);
root_image_paint.setDither(true);
root_image_paint.setFilterBitmap(true);
canvas.drawBitmap(resize_capture_bitmap,100,10,root_image_paint); //이미지 그려줌
TextPaint title_paint = new TextPaint(); // 도화지 위에 그릴 수 있는 Paint클래스 선언
String get_memo = pdf_root_text_memo.getText().toString();
title_paint.setTextAlign(Paint.Align.CENTER); // 가운데 정렬
title_paint.setTypeface(Typeface.create(Typeface.DEFAULT,Typeface.BOLD));
title_paint.setTextSize(17);
// canvas.drawText(get_memo,595/2,500,title_paint);
StaticLayout.Builder builder = StaticLayout.Builder.obtain(get_memo
, 0
, get_memo.length()
, title_paint
, 500 );
StaticLayout textLayout = builder.build();
canvas.save(); // canvas의 저장
canvas.translate(595/2,842/2+90); //canvas의 위치조정
textLayout.draw(canvas); //레이아웃에 저장되어있는 canvas 넣어주기
canvas.restore();
//
//날짜 paint
TextPaint date_paint = new TextPaint(); // 도화지 위에 그릴 수 있는 Paint클래스 선언
date_paint.setTextAlign(Paint.Align.CENTER);
date_paint.setTypeface(Typeface.create(Typeface.DEFAULT,Typeface.BOLD));
date_paint.setTextSize(17);
canvas.drawText("2021-04-21",595/2,842/2+20,date_paint);
//날짜 paint
//장소 paint
TextPaint place_paint = new TextPaint(); // 도화지 위에 그릴 수 있는 Paint클래스 선언
place_paint.setTextAlign(Paint.Align.CENTER);
place_paint.setTypeface(Typeface.create(Typeface.DEFAULT,Typeface.BOLD));
place_paint.setTextSize(17);
canvas.drawText("스코틀랜드",595/2,842/2+50,place_paint);
//장소 paint
pdfDocument.finishPage(page);
이런 방식으로
여행기 정보 DB 에 있는
날짜와 장소, 장소 메모 가지고와서 넣어주면 되는 것 이다.
다음 포스트에는 이 방식으로
여행기 정보 DB에 있는 내용을 가지고 와서
여러 페이지를 담은 PDF를 만들어봐야겠다.
(다음 포스트)
'[Android]' 카테고리의 다른 글
[Android] FCM Push 기능 구현해보자!! (0) | 2021.07.06 |
---|---|
[Android] 프로필 사진을 만들어보자!!(카메라, 앨범, 사진CROP) (0) | 2021.07.03 |
[Android] StaticLayout을 이용해서 Canvas에 텍스트를 MulitLine으로 만들어보자!! (0) | 2021.07.02 |
[Android] 여러 페이지의 PDF를 만들어보자!! (0) | 2021.07.02 |
[Android] Bitmap 이미지의 크기 조정하기 (0) | 2021.07.01 |
Comments