readium-sdk
readium-sdk copied to clipboard
There is any way to get current page and total pages?
Hi,
There is any way to get current page and total pages?
Thanks.
I see example, and i get pages by chapter without problem. But i want get all pages like iBooks. There is a way? Thanks.
Related: https://github.com/readium/readium-js/issues/16
My code to solve part of problems. It gets the page count by section/chapter. But i need get all pages count.
func updateToolbar() {
// total de página e página atual
var pageDataText = ""
if let currentPageOpenPagesArray = currentPageOpenPagesArray {
if currentPageOpenPagesArray.count > 0 {
var pageNumbers = [String]()
for pageDict in currentPageOpenPagesArray {
let spineItemIndex: Int = pageDict["spineItemIndex"] as! Int
let spineItemPageIndex: Int = pageDict["spineItemPageIndex"] as! Int
let pageIndex = currentPageIsFixedLayout ? spineItemIndex : spineItemPageIndex
pageNumbers.append(String(pageIndex + 1))
}
let currentPages = pageNumbers.joined(separator: "-")
var pageCount = 0
if currentPageOpenPagesArray.count > 0 {
let firstOpenPageDict = currentPageOpenPagesArray[0]
let number: Int = firstOpenPageDict["spineItemPageCount"] as! Int
pageCount = currentPageIsFixedLayout ? currentPageSpineItemCount : number
}
// isto pode ser necessário lá na frente
//let pageType = currentPageIsFixedLayout ? "FXL" : "reflow"
pageDataText = String(format: "Página: %@ de %@", currentPages, String(pageCount))
}
}
readerBottomOptions?.lbPage.text = pageDataText
}
Yes, there is a similar implementation in Readium SDK Launcher-iOS: https://github.com/readium/SDKLauncher-iOS/blob/master/Classes/EPubViewController.m#L640-L670
if (m_currentPageOpenPagesArray == nil || [m_currentPageOpenPagesArray count] <= 0) {
label.text = @"";
}
else {
NSMutableArray *pageNumbers = [NSMutableArray array];
for (NSDictionary *pageDict in m_currentPageOpenPagesArray) {
NSNumber *spineItemIndex = [pageDict valueForKey:@"spineItemIndex"];
NSNumber *spineItemPageIndex = [pageDict valueForKey:@"spineItemPageIndex"];
int pageIndex = m_currentPageIsFixedLayout ? spineItemIndex.intValue : spineItemPageIndex.intValue;
[pageNumbers addObject: [NSNumber numberWithInt:pageIndex + 1]];
}
NSString* currentPages = [NSString stringWithFormat:@"%@", [pageNumbers componentsJoinedByString:@"-"]];
int pageCount = 0;
if ([m_currentPageOpenPagesArray count] > 0)
{
NSDictionary *firstOpenPageDict = [m_currentPageOpenPagesArray objectAtIndex:0];
NSNumber *number = [firstOpenPageDict valueForKey:@"spineItemPageCount"];
pageCount = m_currentPageIsFixedLayout ? m_currentPageSpineItemCount: number.intValue;
}
NSString* totalPages = [NSString stringWithFormat:@"%d", pageCount];
label.text = LocStr(@"PAGE_X_OF_Y", [currentPages UTF8String], [totalPages UTF8String], m_currentPageIsFixedLayout?[@"FXL" UTF8String]:[@"reflow" UTF8String]);
}
Hi, i already do it im my project. But it get the current and total pages for the current "chapter".
func updateToolbar() {
// total de páginas e página atual
pageDataText = ""
if let currentPageOpenPagesArray = currentPageOpenPagesArray {
if currentPageOpenPagesArray.count > 0 {
var pageNumbers = [String]()
for pageDict in currentPageOpenPagesArray {
let spineItemIndex: Int = pageDict["spineItemIndex"] as! Int
let spineItemPageIndex: Int = pageDict["spineItemPageIndex"] as! Int
let pageIndex = currentPageIsFixedLayout ? spineItemIndex : spineItemPageIndex
pageNumbers.append(String(pageIndex + 1))
}
let currentPages = pageNumbers.joined(separator: "-")
var pageCount = 0
if currentPageOpenPagesArray.count > 0 {
let firstOpenPageDict = currentPageOpenPagesArray[0]
let number: Int = firstOpenPageDict["spineItemPageCount"] as! Int
pageCount = currentPageIsFixedLayout ? currentPageSpineItemCount : number
}
// isto pode ser necessário lá na frente
//let pageType = currentPageIsFixedLayout ? "FXL" : "reflow"
pageDataText = String(format: "Página: %@ de %@", currentPages, String(pageCount))
}
}
readerBottomOptions?.lbPage.text = pageDataText
}
But i want get the total pages of all chapters/spines.
Hi @paulocoutinhox, did you manage to get current page no and total page count?
Hello @cuneyttyler , did you manage to do it?
@guidomagaldi Yes, I calculated the current page by considering the sizes of each chapter files and looking at the percentage of scroll in the current chapter. I assumed the size of one page is 7 kb. You can use the code below:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class PageCalculator {
private Map<String, Long> sizeMap = new LinkedHashMap<>();
private long totalSize;
private int bytesPerPage = 7000;
public PageCalculator(String filePath) throws IOException {
calcTotalSize(filePath);
}
private void calcTotalSize(String filePath) throws IOException {
ZipFile zip = new ZipFile(filePath);
String content = null;
for (Enumeration e = zip.entries(); e.hasMoreElements(); ) {
ZipEntry entry = (ZipEntry) e.nextElement();
if (!entry.isDirectory() && entry.getName().contains("content.opf")) {
content = getTxtFiles(zip.getInputStream(entry));
}
}
Document doc = Jsoup.parse(content);
Elements spines = doc.getElementsByTag("package").first().getElementsByTag("spine").first().getElementsByTag("itemref");
List<String> chapterFileNames = new ArrayList<>();
for (Element el : spines) {
String id = el.attr("idref");
if(el.attr("linear") == null || !el.attr("linear").equals("no")) {
String chapter = doc.getElementsByTag("package").first().getElementById(id).attr("href");
chapterFileNames.add(chapter);
}
}
for(String chapter: chapterFileNames) {
for (Enumeration e = zip.entries(); e.hasMoreElements(); ) {
ZipEntry entry = (ZipEntry) e.nextElement();
if (!entry.isDirectory() && entry.getName().contains(chapter)) {
sizeMap.put(entry.getName(), entry.getSize());
}
}
}
totalSize = sizeMap.values().stream().reduce(0l,Long::sum);
}
public int getTotalPages() {
return (int)(totalSize / bytesPerPage);
}
public int getCurrentPage(int percent, int chapterIndex) {
long prevSize = 0;
int i = 0;
for(String chapter: sizeMap.keySet()) {
if(chapterIndex == i) {
break;
}
i++;
prevSize += sizeMap.get(chapter);
}
Long currentChapterSize = (Long) sizeMap.values().toArray()[chapterIndex];
double currentChapterSizePerc = currentChapterSize.doubleValue() * ((double)percent/100);
return (int)((prevSize + currentChapterSizePerc ) / bytesPerPage );
}
public class ProgressResponse {
public int chapterIndex;
public double viewScrollMarginPerc;
public ProgressResponse(int chapterIndex, double viewScrollMarginPerc) {
this.chapterIndex = chapterIndex;
this.viewScrollMarginPerc = viewScrollMarginPerc;
}
}
public ProgressResponse getPageFromProgressPercentage(double percent) {
double percSize = (percent * totalSize);
int tempSize = 0;
int progressChapterIndex = 0;
long progressChapterSize = 0;
for(int i = 0; i < sizeMap.size(); i++) {
String chapter = (String) sizeMap.keySet().toArray()[i];
long size = sizeMap.get(chapter);
tempSize += size;
if(tempSize > percSize) {
progressChapterIndex = i;
progressChapterSize = size;
break;
}
}
int prevSize = 0;
for(int i = 0; i < progressChapterIndex; i++) {
String chapter = (String) sizeMap.keySet().toArray()[i];
long size = sizeMap.get(chapter);
prevSize += size;
}
double viewScrollMarginPerc = (percSize - prevSize) / progressChapterSize;
return new ProgressResponse(progressChapterIndex,viewScrollMarginPerc - 0.02);
}
private static String getTxtFiles(InputStream in) {
StringBuilder out = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
try {
while ((line = reader.readLine()) != null) {
out.append(line);
}
} catch (IOException e) {
// do something, probably not a text file
e.printStackTrace();
}
return out.toString();
}
}
@cuneyttyler I will try this, thank you for your time! I really appreciate it :)