Search in sources :

Example 1 with ImageInfo

use of com.github.hmdev.info.ImageInfo in project AozoraEpub3 by hmdev.

the class Epub3ImageWriter method getImageFilePath.

@Override
public String getImageFilePath(String srcImageFileName, int lineNum) {
    boolean isCover = false;
    // xhtmlと画像ファイル名の番号を合わせるため先に++
    this.imageIndex++;
    String ext = "";
    try {
        ext = srcImageFileName.substring(srcImageFileName.lastIndexOf('.') + 1).toLowerCase();
    } catch (Exception e) {
    }
    String imageId = decimalFormat.format(this.imageIndex);
    String imageFileName = IMAGES_PATH + imageId + "." + ext;
    ImageInfo imageInfo;
    try {
        imageInfo = this.imageInfoReader.getImageInfo(srcImageFileName);
        imageInfo.setId(imageId);
        imageInfo.setOutFileName(imageId + "." + ext);
        if (!imageInfo.getExt().matches("^(png|jpeg|gif|jpg)$")) {
            LogAppender.error(lineNum, "画像フォーマットエラー", srcImageFileName);
            return null;
        }
        if (this.imageIndex - 1 == bookInfo.coverImageIndex) {
            imageInfo.setIsCover(true);
            isCover = true;
        }
        this.imageInfos.add(imageInfo);
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
    // 先頭に表紙ページ移動の場合でカバーページならnullを返して本文中から削除
    if (bookInfo.insertCoverPage && isCover)
        return null;
    return "../" + imageFileName;
}
Also used : IOException(java.io.IOException) ImageInfo(com.github.hmdev.info.ImageInfo) IOException(java.io.IOException) RarException(com.github.junrar.exception.RarException)

Example 2 with ImageInfo

use of com.github.hmdev.info.ImageInfo in project AozoraEpub3 by hmdev.

the class Epub3ImageWriter method printSvgImageSection.

/**
 * SVGでセクション出力
 */
private void printSvgImageSection(String srcImageFilePath) throws IOException {
    this.sectionIndex++;
    String sectionId = decimalFormat.format(this.sectionIndex);
    // package.opf用にファイル名
    SectionInfo sectionInfo = new SectionInfo(sectionId);
    ImageInfo imageInfo = this.imageInfoReader.getImageInfo(srcImageFilePath);
    // 画像専用指定
    sectionInfo.setImagePage(true);
    this.sectionInfos.add(sectionInfo);
    // 目次追加
    if (this.sectionIndex == 1 || this.sectionIndex % 5 == 0)
        this.addChapter(null, "" + this.sectionIndex, 0);
    super.zos.putArchiveEntry(new ZipArchiveEntry(OPS_PATH + XHTML_PATH + sectionId + ".xhtml"));
    // ヘッダ出力
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(super.zos, "UTF-8"));
    // 出力開始するセクションに対応したSectionInfoを設定
    this.velocityContext.put("sectionInfo", sectionInfo);
    this.velocityContext.put("imageInfo", imageInfo);
    Velocity.getTemplate(this.templatePath + OPS_PATH + XHTML_PATH + SVG_IMAGE_VM).merge(this.velocityContext, bw);
    bw.flush();
}
Also used : ZipArchiveEntry(org.apache.commons.compress.archivers.zip.ZipArchiveEntry) OutputStreamWriter(java.io.OutputStreamWriter) SectionInfo(com.github.hmdev.info.SectionInfo) ImageInfo(com.github.hmdev.info.ImageInfo) BufferedWriter(java.io.BufferedWriter)

Example 3 with ImageInfo

use of com.github.hmdev.info.ImageInfo in project AozoraEpub3 by hmdev.

the class Epub3Writer method write.

/**
 * epubファイルを出力
 * @param converter 青空文庫テキスト変換クラス 画像のみの場合と切り替えて利用する
 * @param src 青空文庫テキストファイルの入力Stream
 * @param srcFile 青空文庫テキストファイル zip時の画像取得用
 * @param zipTextFileName zipの場合はzip内のテキストファイルのパス付きファイル名
 * @param epubFile 出力ファイル .epub拡張子
 * @param bookInfo 書籍情報と縦横書き指定
 * @param zipImageFileInfos zipの場合はzip内画像の情報 key=サブフォルダ付きの画像ファイル名
 * @throws IOException
 */
public void write(AozoraEpub3Converter converter, BufferedReader src, File srcFile, String srcExt, File epubFile, BookInfo bookInfo, ImageInfoReader imageInfoReader) throws Exception {
    try {
        this.canceled = false;
        this.bookInfo = bookInfo;
        this.imageInfoReader = imageInfoReader;
        // インデックス初期化
        this.sectionIndex = 0;
        this.imageIndex = 0;
        this.sectionInfos.clear();
        this.chapterInfos.clear();
        this.vecGaijiInfo.clear();
        this.gaijiNameSet.clear();
        this.imageInfos.clear();
        this.outImageFileNames.clear();
        // Velocity用 共通コンテキスト設定
        this.velocityContext = new VelocityContext();
        // IDはタイトル著作者のハッシュで適当に生成
        String title = bookInfo.title == null ? "" : bookInfo.title;
        String creator = bookInfo.creator == null ? "" : bookInfo.creator;
        if ("".equals(bookInfo.creator))
            bookInfo.creator = null;
        // 固有ID
        velocityContext.put("identifier", UUID.nameUUIDFromBytes((title + "-" + creator).getBytes()));
        // 表紙の目次表示名
        velocityContext.put("cover_name", "表紙");
        // タイトル &<>はエスケープ
        velocityContext.put("title", CharUtils.escapeHtml(title));
        // タイトル読み &<>はエスケープ
        if (bookInfo.titleAs != null)
            velocityContext.put("titleAs", CharUtils.escapeHtml(bookInfo.titleAs));
        // 著者 &<>はエスケープ
        velocityContext.put("creator", CharUtils.escapeHtml(creator));
        // 著者読み &<>はエスケープ
        if (bookInfo.creatorAs != null)
            velocityContext.put("creatorAs", CharUtils.escapeHtml(bookInfo.creatorAs));
        // 刊行者情報
        if (bookInfo.publisher != null)
            velocityContext.put("publisher", bookInfo.publisher);
        // 書籍情報
        velocityContext.put("bookInfo", bookInfo);
        // 更新日時
        velocityContext.put("modified", dateFormat.format(bookInfo.modified));
        // 目次階層化
        velocityContext.put("navNest", this.navNest);
        // 端末種別
        if (this.isKindle)
            velocityContext.put("kindle", true);
        // SVG画像出力
        if (this.isSvgImage)
            velocityContext.put("svgImage", true);
        // スタイル
        velocityContext.put("pageMargin", this.pageMargin);
        velocityContext.put("bodyMargin", this.bodyMargin);
        velocityContext.put("lineHeight", this.lineHeight);
        velocityContext.put("fontSize", this.fontSize);
        velocityContext.put("boldUseGothic", this.boldUseGothic);
        velocityContext.put("gothicUseBold", this.gothicUseBold);
        // 出力先ePubのZipストリーム生成
        zos = new ZipArchiveOutputStream(new BufferedOutputStream(new FileOutputStream(epubFile)));
        // mimetypeは非圧縮
        // STOREDで格納しCRCとsizeを指定する必要がある
        ZipArchiveEntry mimeTypeEntry = new ZipArchiveEntry(MIMETYPE_PATH);
        FileInputStream fis = new FileInputStream(new File(templatePath + MIMETYPE_PATH));
        byte[] b = new byte[256];
        int len = fis.read(b);
        fis.close();
        CRC32 crc32 = new CRC32();
        crc32.update(b, 0, len);
        mimeTypeEntry.setMethod(ZipArchiveEntry.STORED);
        mimeTypeEntry.setCrc(crc32.getValue());
        mimeTypeEntry.setSize(len);
        zos.putArchiveEntry(mimeTypeEntry);
        zos.write(b, 0, len);
        b = null;
        zos.closeArchiveEntry();
        zos.setLevel(9);
        // テンプレートのファイルを格納
        for (String fileName : getTemplateFiles()) {
            writeFile(zos, fileName);
        }
        // サブパスの文字長
        int archivePathLength = 0;
        if (this.bookInfo.textEntryName != null)
            archivePathLength = this.bookInfo.textEntryName.indexOf('/') + 1;
        // zip出力用Writer
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(zos, "UTF-8"));
        // 本文を出力
        this.writeSections(converter, src, bw, srcFile, srcExt, zos);
        if (this.canceled)
            return;
        // 外字のcssを格納
        velocityContext.put("vecGaijiInfo", this.vecGaijiInfo);
        // スタイルと外字のcssを格納
        if (bookInfo.vertical) {
            zos.putArchiveEntry(new ZipArchiveEntry(OPS_PATH + CSS_PATH + VERTICAL_TEXT_CSS));
            bw = new BufferedWriter(new OutputStreamWriter(zos, "UTF-8"));
            Velocity.mergeTemplate(templatePath + OPS_PATH + CSS_PATH + VERTICAL_TEXT_CSS_VM, "UTF-8", velocityContext, bw);
            bw.flush();
            zos.closeArchiveEntry();
        } else {
            zos.putArchiveEntry(new ZipArchiveEntry(OPS_PATH + CSS_PATH + HORIZONTAL_TEXT_CSS));
            bw = new BufferedWriter(new OutputStreamWriter(zos, "UTF-8"));
            Velocity.mergeTemplate(templatePath + OPS_PATH + CSS_PATH + HORIZONTAL_TEXT_CSS_VM, "UTF-8", velocityContext, bw);
            bw.flush();
            zos.closeArchiveEntry();
        }
        // 表紙をテンプレート+メタ情報から生成 先に出力すると外字画像出力で表紙の順番が狂う
        if (!bookInfo.imageOnly && (bookInfo.titlePageType == BookInfo.TITLE_MIDDLE || bookInfo.titlePageType == BookInfo.TITLE_HORIZONTAL)) {
            String vmFilePath = templatePath + OPS_PATH + XHTML_PATH + TITLE_M_VM;
            if (bookInfo.titlePageType == BookInfo.TITLE_HORIZONTAL) {
                converter.vertical = false;
                vmFilePath = templatePath + OPS_PATH + XHTML_PATH + TITLE_H_VM;
            }
            // ルビと外字画像注記と縦中横注記(縦書きのみ)のみ変換する
            String line = bookInfo.getTitleText();
            if (line != null)
                velocityContext.put("TITLE", converter.convertTitleLineToEpub3(line));
            line = bookInfo.getSubTitleText();
            if (line != null)
                velocityContext.put("SUBTITLE", converter.convertTitleLineToEpub3(line));
            line = bookInfo.getOrgTitleText();
            if (line != null)
                velocityContext.put("ORGTITLE", converter.convertTitleLineToEpub3(line));
            line = bookInfo.getSubOrgTitleText();
            if (line != null)
                velocityContext.put("SUBORGTITLE", converter.convertTitleLineToEpub3(line));
            line = bookInfo.getCreatorText();
            if (line != null)
                velocityContext.put("CREATOR", converter.convertTitleLineToEpub3(line));
            line = bookInfo.getSubCreatorText();
            if (line != null)
                velocityContext.put("SUBCREATOR", converter.convertTitleLineToEpub3(line));
            line = bookInfo.getSeriesText();
            if (line != null)
                velocityContext.put("SERIES", converter.convertTitleLineToEpub3(line));
            line = bookInfo.getPublisherText();
            if (line != null)
                velocityContext.put("PUBLISHER", converter.convertTitleLineToEpub3(line));
            // package.opf内で目次前に出力
            zos.putArchiveEntry(new ZipArchiveEntry(OPS_PATH + XHTML_PATH + TITLE_FILE));
            bw = new BufferedWriter(new OutputStreamWriter(zos, "UTF-8"));
            Velocity.mergeTemplate(vmFilePath, "UTF-8", velocityContext, bw);
            bw.flush();
            zos.closeArchiveEntry();
            velocityContext.put("title_page", true);
            // 表題行を目次に出力するならtitle.xhtmlを追加 (本文内の行はchapterinfosに追加されていない)
            ChapterLineInfo titleLineInfo = bookInfo.getChapterLineInfo(bookInfo.titleLine);
            if (titleLineInfo != null) {
                chapterInfos.add(0, new ChapterInfo("title", null, bookInfo.title, ChapterLineInfo.LEVEL_TITLE));
            }
        }
        if (this.canceled)
            return;
        // 表紙データと表示の画像情報
        byte[] coverImageBytes = null;
        ImageInfo coverImageInfo = null;
        if (bookInfo.coverFileName != null && bookInfo.coverFileName.length() > 0) {
            // 表紙情報をimageInfosに追加
            try {
                // 表紙設定解除
                for (ImageInfo imageInfo2 : imageInfos) {
                    imageInfo2.setIsCover(false);
                }
                BufferedInputStream bis;
                if (bookInfo.coverFileName.startsWith("http")) {
                    bis = new BufferedInputStream(new URL(bookInfo.coverFileName).openStream(), 8192);
                } else {
                    bis = new BufferedInputStream(new FileInputStream(new File(bookInfo.coverFileName)), 8192);
                }
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                IOUtils.copy(bis, baos);
                coverImageBytes = baos.toByteArray();
                bis.close();
                baos.close();
                ByteArrayInputStream bais = new ByteArrayInputStream(coverImageBytes);
                coverImageInfo = ImageInfo.getImageInfo(bais);
                bais.close();
                String ext = coverImageInfo.getExt();
                if (isKindle || ext.equals("jpeg"))
                    ext = "jpg";
                coverImageInfo.setId("0000");
                coverImageInfo.setOutFileName("0000." + ext);
                if (!ext.matches("^(png|jpg|jpeg|gif)$")) {
                    LogAppender.println("表紙画像フォーマットエラー: " + bookInfo.coverFileName);
                    coverImageInfo = null;
                } else {
                    coverImageInfo.setIsCover(true);
                    this.imageInfos.add(0, coverImageInfo);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (bookInfo.coverImage != null) {
            // すべてのページの表紙設定解除
            for (ImageInfo imageInfo2 : imageInfos) {
                imageInfo2.setIsCover(false);
            }
            // プレビューでトリミングされた表紙
            String ext = "jpg";
            if (bookInfo.coverExt != null) {
                ext = bookInfo.coverExt;
            } else if (bookInfo.coverImageIndex > -1) {
                ImageInfo imageInfo = imageInfoReader.getImageInfo(bookInfo.coverImageIndex);
                if (imageInfo != null)
                    ext = imageInfo.getExt();
            }
            if (isKindle || ext.equals("jpeg"))
                ext = "jpg";
            coverImageInfo = ImageInfo.getImageInfo(ext, bookInfo.coverImage, -1);
            coverImageInfo.setId("0000");
            coverImageInfo.setOutFileName("0000." + ext);
            coverImageInfo.setIsCover(true);
            this.imageInfos.add(0, coverImageInfo);
        } else {
            // 本文にないzip内の表紙を出力対象に追加 (テキストからの相対パス)
            if (bookInfo.coverImageIndex > -1 && imageInfoReader.countImageFileNames() > bookInfo.coverImageIndex) {
                if (!"txt".equals(srcExt)) {
                    String imageFileName = imageInfoReader.getImageFileName(bookInfo.coverImageIndex);
                    if (imageFileName != null) {
                        ImageInfo imageInfo = imageInfoReader.getImageInfo(imageFileName);
                        if (imageInfo != null) {
                            imageFileName = imageFileName.substring(archivePathLength);
                            outImageFileNames.add(imageFileName);
                            // 表紙フラグも設定
                            for (ImageInfo imageInfo2 : imageInfos) {
                                imageInfo2.setIsCover(false);
                            }
                            imageInfo.setIsCover(true);
                            if (!this.imageInfos.contains(imageInfo))
                                this.imageInfos.add(imageInfo);
                        }
                    }
                }
            }
        }
        // 表紙ページ出力 先頭画像表示時は画像出力時にカバー指定するので出力しない
        if (bookInfo.insertCoverPage) {
            // 追加用の情報取得にのみ使う
            ImageInfo insertCoverInfo = coverImageInfo;
            if (insertCoverInfo == null && bookInfo.coverImageIndex > -1) {
                // 本文中の挿絵の場合
                insertCoverInfo = imageInfoReader.getImageInfo(bookInfo.coverImageIndex);
                if (insertCoverInfo != null) {
                    insertCoverInfo.setIsCover(true);
                    if (!bookInfo.imageOnly && insertCoverInfo.getId() == null) {
                        // zip内の画像で追加処理されていない
                        this.imageIndex++;
                        String imageId = decimalFormat.format(this.imageIndex);
                        insertCoverInfo.setId(imageId);
                        String ext = insertCoverInfo.getExt();
                        if (isKindle)
                            ext = "jpg";
                        insertCoverInfo.setOutFileName(imageId + "." + ext);
                    }
                }
            }
            if (insertCoverInfo != null) {
                SectionInfo sectionInfo = new SectionInfo("cover-page");
                if (this.imageSizeType != SectionInfo.IMAGE_SIZE_TYPE_AUTO) {
                    // 画像が横長なら幅100% それ以外は高さ100%
                    if ((double) insertCoverInfo.getWidth() / insertCoverInfo.getHeight() >= (double) this.coverW / this.coverH)
                        sectionInfo.setImageFitW(true);
                    else
                        sectionInfo.setImageFitH(true);
                } else {
                    sectionInfo.setImageFitW(false);
                    sectionInfo.setImageFitH(false);
                }
                this.velocityContext.put("sectionInfo", sectionInfo);
                this.velocityContext.put("coverImage", insertCoverInfo);
                zos.putArchiveEntry(new ZipArchiveEntry(OPS_PATH + XHTML_PATH + COVER_FILE));
                bw = new BufferedWriter(new OutputStreamWriter(zos, "UTF-8"));
                Velocity.mergeTemplate(templatePath + OPS_PATH + XHTML_PATH + COVER_VM, "UTF-8", velocityContext, bw);
                bw.flush();
                zos.closeArchiveEntry();
            } else {
                // 画像がなかったら表紙ページ無し
                bookInfo.insertCoverPage = false;
            }
        }
        // package.opf 出力
        velocityContext.put("sections", sectionInfos);
        velocityContext.put("images", imageInfos);
        zos.putArchiveEntry(new ZipArchiveEntry(OPS_PATH + PACKAGE_FILE));
        bw = new BufferedWriter(new OutputStreamWriter(zos, "UTF-8"));
        Velocity.mergeTemplate(templatePath + OPS_PATH + PACKAGE_VM, "UTF-8", velocityContext, bw);
        bw.flush();
        zos.closeArchiveEntry();
        // nullを除去
        for (int i = chapterInfos.size() - 1; i >= 0; i--) {
            if (chapterInfos.get(i).getChapterName() == null)
                chapterInfos.remove(i);
        }
        // 表題のレベルを2つめと同じにする
        if (bookInfo.insertTitleToc && chapterInfos.size() >= 2) {
            chapterInfos.get(0).chapterLevel = chapterInfos.get(1).chapterLevel;
        }
        // 目次の階層情報を設定
        // レベルを0から開始に変更
        int[] chapterCounts = new int[10];
        for (ChapterInfo chapterInfo : chapterInfos) {
            chapterCounts[chapterInfo.getChapterLevel()]++;
        }
        int[] newLevel = new int[10];
        int level = 0;
        for (int i = 0; i < chapterCounts.length; i++) {
            if (chapterCounts[i] > 0)
                newLevel[i] = level++;
        }
        for (ChapterInfo chapterInfo : chapterInfos) {
            chapterInfo.chapterLevel = newLevel[chapterInfo.chapterLevel];
        }
        // 開始終了情報を追加 nav用
        // レベル0
        ChapterInfo preChapterInfo = new ChapterInfo(null, null, null, 0);
        for (ChapterInfo chapterInfo : chapterInfos) {
            if (preChapterInfo != null) {
                // 開始
                chapterInfo.levelStart = Math.max(0, chapterInfo.chapterLevel - preChapterInfo.chapterLevel);
                // 終了
                preChapterInfo.levelEnd = Math.max(0, preChapterInfo.chapterLevel - chapterInfo.chapterLevel);
            }
            preChapterInfo = chapterInfo;
        }
        // 一番最後は閉じる
        if (chapterInfos.size() > 0) {
            ChapterInfo chapterInfo = chapterInfos.lastElement();
            if (chapterInfo != null)
                chapterInfo.levelEnd = chapterInfo.chapterLevel;
        }
        int ncxDepth = 1;
        if (this.ncxNest) {
            int minLevel = 99;
            int maxLevel = 0;
            // navPointを閉じる回数をlevelEndに設定
            // navPointを開始したレベルidxに1を設定
            int[] navPointLevel = new int[10];
            preChapterInfo = null;
            for (ChapterInfo chapterInfo : chapterInfos) {
                if (preChapterInfo != null) {
                    int preLevel = preChapterInfo.chapterLevel;
                    int curLevel = chapterInfo.chapterLevel;
                    minLevel = Math.min(minLevel, curLevel);
                    maxLevel = Math.max(maxLevel, curLevel);
                    navPointLevel[preLevel] = 1;
                    if (preLevel < curLevel) {
                        // 前より小さい場合
                        preChapterInfo.navClose = 0;
                    } else if (preLevel > curLevel) {
                        // 前より大きい
                        int close = 0;
                        for (int i = curLevel; i < navPointLevel.length; i++) {
                            if (navPointLevel[i] == 1) {
                                close++;
                                navPointLevel[i] = 0;
                            }
                        }
                        preChapterInfo.navClose = close;
                    } else {
                        preChapterInfo.navClose = 1;
                        navPointLevel[preLevel] = 0;
                    }
                }
                preChapterInfo = chapterInfo;
            }
            if (minLevel < maxLevel)
                ncxDepth = maxLevel - minLevel + 1;
            // 一番最後は閉じる
            if (chapterInfos.size() > 0) {
                ChapterInfo chapterInfo = chapterInfos.lastElement();
                if (chapterInfo != null) {
                    int close = 1;
                    for (int i = 0; i < navPointLevel.length; i++) {
                        if (navPointLevel[i] == 1) {
                            close++;
                        }
                    }
                    chapterInfo.navClose = close;
                }
            }
        }
        // velocityに設定 1~
        velocityContext.put("ncx_depth", ncxDepth);
        // 出力前に縦中横とエスケープ処理
        if (!bookInfo.imageOnly) {
            converter.vertical = bookInfo.tocVertical;
            int spaceHyphenation = converter.getSpaceHyphenation();
            converter.setSpaceHyphenation(0);
            StringBuilder buf = new StringBuilder();
            for (ChapterInfo chapterInfo : chapterInfos) {
                buf.setLength(0);
                String converted = CharUtils.escapeHtml(chapterInfo.getChapterName());
                if (bookInfo.tocVertical) {
                    converted = converter.convertTcyText(converted);
                }
                chapterInfo.setChapterName(converted);
            }
            // 戻す
            converter.vertical = bookInfo.vertical;
            converter.setSpaceHyphenation(spaceHyphenation);
        }
        // navファイル
        velocityContext.put("chapters", chapterInfos);
        zos.putArchiveEntry(new ZipArchiveEntry(OPS_PATH + XHTML_PATH + XHTML_NAV_FILE));
        bw = new BufferedWriter(new OutputStreamWriter(zos, "UTF-8"));
        Velocity.mergeTemplate(templatePath + OPS_PATH + XHTML_PATH + XHTML_NAV_VM, "UTF-8", velocityContext, bw);
        bw.flush();
        zos.closeArchiveEntry();
        // tocファイル
        velocityContext.put("chapters", chapterInfos);
        zos.putArchiveEntry(new ZipArchiveEntry(OPS_PATH + TOC_FILE));
        bw = new BufferedWriter(new OutputStreamWriter(zos, "UTF-8"));
        Velocity.mergeTemplate(templatePath + OPS_PATH + TOC_VM, "UTF-8", velocityContext, bw);
        bw.flush();
        zos.closeArchiveEntry();
        if (src != null)
            src.close();
        if (this.canceled)
            return;
        // プログレスバーにテキスト進捗分を追加
        if (this.jProgressBar != null && !bookInfo.imageOnly)
            this.jProgressBar.setValue(bookInfo.totalLineNum / 10);
        // フォントファイル格納
        if (!bookInfo.imageOnly) {
            File fontsPath = new File(templatePath + OPS_PATH + FONTS_PATH);
            if (fontsPath.exists()) {
                for (File fontFile : fontsPath.listFiles()) {
                    String outFileName = OPS_PATH + FONTS_PATH + fontFile.getName();
                    zos.putArchiveEntry(new ZipArchiveEntry(outFileName));
                    fis = new FileInputStream(new File(templatePath + outFileName));
                    IOUtils.copy(fis, zos);
                    fis.close();
                    zos.closeArchiveEntry();
                }
            }
        }
        // 外字ファイル格納
        for (GaijiInfo gaijiInfo : this.vecGaijiInfo) {
            File gaijiFile = gaijiInfo.getFile();
            if (gaijiFile.exists()) {
                String outFileName = OPS_PATH + GAIJI_PATH + gaijiFile.getName();
                zos.putArchiveEntry(new ZipArchiveEntry(outFileName));
                fis = new FileInputStream(gaijiFile);
                IOUtils.copy(fis, zos);
                fis.close();
                zos.closeArchiveEntry();
            }
        }
        zos.setLevel(0);
        // 表紙編集時のイメージ出力
        if (coverImageInfo != null) {
            try {
                // kindleの場合は常にjpegに変換
                if (isKindle) {
                    String imgExt = coverImageInfo.getExt();
                    if (!imgExt.startsWith("jp")) {
                        if (bookInfo.coverImage == null) {
                            ByteArrayInputStream bais = new ByteArrayInputStream(coverImageBytes);
                            bookInfo.coverImage = ImageUtils.readImage(imgExt, bais);
                            bais.close();
                        }
                        coverImageInfo.setExt("jpeg");
                    }
                }
                if (bookInfo.coverImage != null) {
                    // プレビューで編集されている場合
                    zos.putArchiveEntry(new ZipArchiveEntry(OPS_PATH + IMAGES_PATH + coverImageInfo.getOutFileName()));
                    this.writeCoverImage(bookInfo.coverImage, zos, coverImageInfo);
                    zos.closeArchiveEntry();
                    // 同じ画像が使われている場合は以後はファイルから読み込ませる
                    bookInfo.coverImage = null;
                } else {
                    ByteArrayInputStream bais = new ByteArrayInputStream(coverImageBytes);
                    zos.putArchiveEntry(new ZipArchiveEntry(OPS_PATH + IMAGES_PATH + coverImageInfo.getOutFileName()));
                    this.writeCoverImage(bais, zos, coverImageInfo);
                    zos.closeArchiveEntry();
                    bais.close();
                }
                // カバー画像は出力済みなので削除
                imageInfos.remove(0);
                if (this.jProgressBar != null)
                    this.jProgressBar.setValue(this.jProgressBar.getValue() + 10);
            } catch (Exception e) {
                e.printStackTrace();
                LogAppender.error("表紙画像取得エラー: " + bookInfo.coverFileName);
            }
        }
        if (this.canceled)
            return;
        // 本文画像出力 (画像のみの場合は出力済)
        if ("txt".equals(srcExt)) {
            // txtの場合はファイルシステムから取得
            for (String srcImageFileName : imageInfoReader.getImageFileNames()) {
                // 拡張子修正
                srcImageFileName = imageInfoReader.correctExt(srcImageFileName);
                if (outImageFileNames.contains(srcImageFileName)) {
                    ImageInfo imageInfo = imageInfoReader.getImageInfo(srcImageFileName);
                    if (imageInfo == null) {
                        LogAppender.println("[WARN] 画像ファイルなし: " + srcImageFileName);
                    } else {
                        File imageFile = imageInfoReader.getImageFile(srcImageFileName);
                        if (imageFile.exists()) {
                            fis = new FileInputStream(imageFile);
                            zos.putArchiveEntry(new ZipArchiveEntry(OPS_PATH + IMAGES_PATH + imageInfo.getOutFileName()));
                            this.writeImage(new BufferedInputStream(fis, 8192), zos, imageInfo);
                            zos.closeArchiveEntry();
                            fis.close();
                            outImageFileNames.remove(srcImageFileName);
                        }
                    }
                }
                if (this.canceled)
                    return;
                if (this.jProgressBar != null)
                    this.jProgressBar.setValue(this.jProgressBar.getValue() + 10);
            }
        } else if (!bookInfo.imageOnly) {
            if ("rar".equals(srcExt)) {
                // //////////////////////////////
                // Rar
                Archive archive = new Archive(srcFile);
                try {
                    for (FileHeader fileHeader : archive.getFileHeaders()) {
                        if (!fileHeader.isDirectory()) {
                            String entryName = fileHeader.getFileNameW();
                            if (entryName.length() == 0)
                                entryName = fileHeader.getFileNameString();
                            entryName = entryName.replace('\\', '/');
                            // アーカイブ内のサブフォルダは除外してテキストからのパスにする
                            String srcImageFileName = entryName.substring(archivePathLength);
                            if (outImageFileNames.contains(srcImageFileName)) {
                                InputStream is = archive.getInputStream(fileHeader);
                                try {
                                    this.writeArchiveImage(srcImageFileName, is);
                                } finally {
                                    is.close();
                                }
                            }
                        }
                    }
                } finally {
                    archive.close();
                }
            } else {
                // //////////////////////////////
                // Zip
                ZipArchiveInputStream zis = new ZipArchiveInputStream(new BufferedInputStream(new FileInputStream(srcFile), 65536), "MS932", false);
                try {
                    ArchiveEntry entry;
                    while ((entry = zis.getNextZipEntry()) != null) {
                        // アーカイブ内のサブフォルダは除外してテキストからのパスにする
                        String srcImageFileName = entry.getName().substring(archivePathLength);
                        if (outImageFileNames.contains(srcImageFileName)) {
                            this.writeArchiveImage(srcImageFileName, zis);
                        }
                    }
                } finally {
                    zis.close();
                }
            }
        }
        // エラーがなければ100%
        if (this.jProgressBar != null)
            this.jProgressBar.setValue(this.jProgressBar.getMaximum());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            // ePub3出力ファイルを閉じる
            if (zos != null)
                zos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // メンバ変数解放
        this.velocityContext = null;
        this.bookInfo = null;
        this.imageInfoReader = null;
    }
}
Also used : ChapterInfo(com.github.hmdev.info.ChapterInfo) Archive(com.github.junrar.Archive) CRC32(java.util.zip.CRC32) VelocityContext(org.apache.velocity.VelocityContext) ZipArchiveEntry(org.apache.commons.compress.archivers.zip.ZipArchiveEntry) ArchiveEntry(org.apache.commons.compress.archivers.ArchiveEntry) URL(java.net.URL) BufferedWriter(java.io.BufferedWriter) BufferedInputStream(java.io.BufferedInputStream) ZipArchiveEntry(org.apache.commons.compress.archivers.zip.ZipArchiveEntry) ImageInfo(com.github.hmdev.info.ImageInfo) BufferedOutputStream(java.io.BufferedOutputStream) FileHeader(com.github.junrar.rarfile.FileHeader) ZipArchiveInputStream(org.apache.commons.compress.archivers.zip.ZipArchiveInputStream) BufferedInputStream(java.io.BufferedInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) FileInputStream(java.io.FileInputStream) ZipArchiveInputStream(org.apache.commons.compress.archivers.zip.ZipArchiveInputStream) InputStream(java.io.InputStream) ChapterLineInfo(com.github.hmdev.info.ChapterLineInfo) ZipArchiveOutputStream(org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) FileInputStream(java.io.FileInputStream) IOException(java.io.IOException) ByteArrayInputStream(java.io.ByteArrayInputStream) FileOutputStream(java.io.FileOutputStream) OutputStreamWriter(java.io.OutputStreamWriter) SectionInfo(com.github.hmdev.info.SectionInfo) GaijiInfo(com.github.hmdev.info.GaijiInfo) File(java.io.File)

Example 4 with ImageInfo

use of com.github.hmdev.info.ImageInfo in project AozoraEpub3 by hmdev.

the class AozoraEpub3Converter method getBookInfo.

/**
 * タイトルと著作者を取得. 行番号も保存して出力時に変換出力
 * 章洗濯用に見出しの行もここで取得
 * @param src 青空テキストファイルのReader
 * @param imageInfoReader テキスト内の画像ファイル名を格納して返却
 * @param titleType 表題種別
 * @param coverFileName 表紙ファイル名 nullなら表紙無し ""は先頭ファイル "*"は同じファイル名
 */
public BookInfo getBookInfo(File srcFile, BufferedReader src, ImageInfoReader imageInfoReader, TitleType titleType, boolean pubFirst) throws Exception {
    try {
        BookInfo bookInfo = new BookInfo(srcFile);
        String line;
        this.lineNum = -1;
        // 前の行のバッファ [1行前, 2行前]
        String[] preLines = new String[] { null, null };
        // コメントブロック内
        boolean inComment = false;
        // コメントが始まったらtrue
        boolean firstCommentStarted = false;
        // 最初のコメント開始行
        int firstCommentLineNum = -1;
        // 先頭行
        String[] firstLines = new String[10];
        // 先頭行の開始行番号
        int firstLineStart = -1;
        // タイトルページ開始行 画像等がなければ-1 タイトルなしは-2
        // int preTitlePageBreak = titleType==TitleType.NONE ? -2 : -1;
        // コメント内の行数
        int commentLineNum = 0;
        // コメント開始行
        int commentLineStart = -1;
        // 直線の空行
        int lastEmptyLine = -1;
        // 目次用見出し自動抽出
        boolean autoChapter = this.autoChapterName || this.autoChapterNumTitle || this.autoChapterNumOnly || this.autoChapterNumParen || this.autoChapterNumParenTitle || this.chapterPattern != null;
        // 改ページ後の目次を追加するならtrue
        boolean addSectionChapter = true;
        // 見出し注記の後の文字を追加
        boolean addChapterName = false;
        // 見出しの次の行を繋げるときに見出しの次の行番号を設定
        int addNextChapterName = -1;
        // ブロック見出し注記、次の行を繋げる場合に設定
        ChapterLineInfo preChapterLineInfo = null;
        // 最後まで回す
        while ((line = src.readLine()) != null) {
            this.lineNum++;
            // 見出し等の取得のため前方参照注記は変換 外字文字は置換
            line = CharUtils.removeSpace(this.replaceChukiSufTag(this.convertGaijiChuki(line, true, false)));
            // 注記と画像のチェックなので先にルビ除去
            String noRubyLine = CharUtils.removeRuby(line);
            // コメント除外 50文字以上をコメントにする
            if (noRubyLine.startsWith("--------------------------------")) {
                if (!noRubyLine.startsWith("--------------------------------------------------")) {
                    LogAppender.warn(lineNum, "コメント行の文字数が足りません");
                } else {
                    if (firstCommentLineNum == -1)
                        firstCommentLineNum = this.lineNum;
                    // コメントブロックに入ったらタイトル著者終了
                    firstCommentStarted = true;
                    if (inComment) {
                        // コメント行終了
                        if (commentLineNum > 20)
                            LogAppender.warn(lineNum, "コメントが " + commentLineNum + " 行 (" + (commentLineStart + 1) + ") -");
                        commentLineNum = 0;
                        inComment = false;
                        continue;
                    } else {
                        if (lineNum > 10 && !(commentPrint && commentConvert))
                            LogAppender.warn(lineNum, "コメント開始行が10行目以降にあります");
                        // コメント行開始
                        commentLineStart = this.lineNum;
                        inComment = true;
                        continue;
                    }
                }
                if (inComment)
                    commentLineNum++;
            }
            // 空行チェック
            if (noRubyLine.equals("") || noRubyLine.equals(" ") || noRubyLine.equals(" ")) {
                lastEmptyLine = lineNum;
                // 空行なので次の行へ
                continue;
            }
            if (inComment && !this.commentPrint)
                continue;
            // 2行前が改ページと画像の行かをチェックして行番号をbookInfoに保存
            if (!noIllust)
                this.checkImageOnly(bookInfo, preLines, noRubyLine, this.lineNum);
            // 見出しのChapter追加
            if (addChapterName) {
                if (// 前の見出しがなければ中止
                preChapterLineInfo == null)
                    // 前の見出しがなければ中止
                    addChapterName = false;
                else {
                    String name = this.getChapterName(noRubyLine);
                    // 字下げ注記等は飛ばして次の行を見る
                    if (name.length() > 0) {
                        preChapterLineInfo.setChapterName(name);
                        preChapterLineInfo.lineNum = lineNum;
                        addChapterName = false;
                        // 次の行を繋げる設定
                        if (this.useNextLineChapterName)
                            addNextChapterName = lineNum + 1;
                        // 改ページ後のChapter出力を抑止
                        addSectionChapter = false;
                    }
                    // 必ず文字が入る
                    preChapterLineInfo = null;
                }
            }
            // 画像のファイル名の順にimageInfoReaderにファイル名を追加
            Matcher m = chukiPattern.matcher(noRubyLine);
            while (m.find()) {
                String chukiTag = m.group();
                String chukiName = chukiTag.substring(2, chukiTag.length() - 1);
                if (chukiFlagPageBreak.contains(chukiName)) {
                    // 改ページ注記ならフラグON
                    addSectionChapter = true;
                } else if (chapterChukiMap.containsKey(chukiName)) {
                    // 見出し注記
                    // 注記の後に文字がなければブロックなので次の行 (次の行にブロック注記はこない?)
                    int chapterType = chapterChukiMap.get(chukiName);
                    if (noRubyLine.length() == m.start() + chukiTag.length()) {
                        preChapterLineInfo = new ChapterLineInfo(lineNum + 1, chapterType, addSectionChapter, ChapterLineInfo.getLevel(chapterType), lastEmptyLine == lineNum - 1);
                        bookInfo.addChapterLineInfo(preChapterLineInfo);
                        // 次の行を見出しとして利用
                        addChapterName = true;
                        addNextChapterName = -1;
                    } else {
                        bookInfo.addChapterLineInfo(new ChapterLineInfo(lineNum, chapterType, addSectionChapter, ChapterLineInfo.getLevel(chapterType), lastEmptyLine == lineNum - 1, this.getChapterName(noRubyLine.substring(m.end()))));
                        // 次の行を連結
                        if (this.useNextLineChapterName)
                            addNextChapterName = lineNum + 1;
                        // 次の行を見出しとして利用しない
                        addChapterName = false;
                    }
                    // 改ページ後のChapter出力を抑止
                    addSectionChapter = false;
                }
                String lowerChukiTag = chukiTag.toLowerCase();
                int imageStartIdx = chukiTag.lastIndexOf('(');
                if (imageStartIdx > -1) {
                    int imageEndIdx = chukiTag.indexOf(")", imageStartIdx);
                    int imageDotIdx = chukiTag.indexOf('.', imageStartIdx);
                    // 訓点送り仮名チェック #の次が(で.を含まない
                    if (imageDotIdx > -1 && imageDotIdx < imageEndIdx) {
                        // 画像ファイル名を取得し画像情報を格納
                        String imageFileName = this.getImageChukiFileName(chukiTag, imageStartIdx);
                        if (imageFileName != null) {
                            imageInfoReader.addImageFileName(imageFileName);
                            if (bookInfo.firstImageLineNum == -1) {
                                // 小さい画像は無視
                                ImageInfo imageInfo = imageInfoReader.getImageInfo(imageInfoReader.correctExt(imageFileName));
                                if (imageInfo != null && imageInfo.getWidth() > 64 && imageInfo.getHeight() > 64) {
                                    bookInfo.firstImageLineNum = lineNum;
                                    bookInfo.firstImageIdx = imageInfoReader.countImageFileNames() - 1;
                                }
                            }
                        }
                    }
                } else if (lowerChukiTag.startsWith("<img")) {
                    // src=の値抽出
                    String imageFileName = this.getTagAttr(chukiTag, "src");
                    if (imageFileName != null) {
                        // 画像がなければそのまま追加
                        imageInfoReader.addImageFileName(imageFileName);
                        if (bookInfo.firstImageLineNum == -1) {
                            // 小さい画像は無視
                            ImageInfo imageInfo = imageInfoReader.getImageInfo(imageInfoReader.correctExt(imageFileName));
                            if (imageInfo != null && imageInfo.getWidth() > 64 && imageInfo.getHeight() > 64) {
                                bookInfo.firstImageLineNum = lineNum;
                                bookInfo.firstImageIdx = imageInfoReader.countImageFileNames() - 1;
                            }
                        }
                    }
                }
            }
            // TODO パターンと目次レベルは設定可能にする 空行指定の場合はpreLines利用
            if (autoChapter && bookInfo.getChapterLevel(lineNum) == 0) {
                // 文字列から注記と前の空白を除去
                String noChukiLine = CharUtils.removeSpace(CharUtils.removeTag(noRubyLine));
                // その他パターン
                if (this.chapterPattern != null) {
                    if (this.chapterPattern.matcher(noChukiLine).find()) {
                        bookInfo.addChapterLineInfo(new ChapterLineInfo(lineNum, ChapterLineInfo.TYPE_PATTERN, addSectionChapter, ChapterLineInfo.getLevel(ChapterLineInfo.TYPE_PATTERN), lastEmptyLine == lineNum - 1, this.getChapterName(noRubyLine)));
                        // 次の行を連結
                        if (this.useNextLineChapterName)
                            addNextChapterName = lineNum + 1;
                        // 改ページ後のChapter出力を抑止
                        addSectionChapter = false;
                    }
                }
                int noChukiLineLength = noChukiLine.length();
                if (this.autoChapterName) {
                    boolean isChapter = false;
                    // 数字を含まない章名
                    for (int i = 0; i < this.chapterName.length; i++) {
                        String prefix = this.chapterName[i];
                        if (noChukiLine.startsWith(prefix)) {
                            if (noChukiLine.length() == prefix.length()) {
                                isChapter = true;
                                break;
                            } else if (isChapterSeparator(noChukiLine.charAt(prefix.length()))) {
                                isChapter = true;
                                break;
                            }
                        }
                    }
                    // 数字を含む章名
                    if (!isChapter) {
                        for (int i = 0; i < this.chapterNumPrefix.length; i++) {
                            String prefix = this.chapterNumPrefix[i];
                            if (noChukiLine.startsWith(prefix)) {
                                int idx = prefix.length();
                                // 次が数字かチェック
                                while (noChukiLineLength > idx && isChapterNum(noChukiLine.charAt(idx))) idx++;
                                // 数字がなければ抽出しない
                                if (idx <= prefix.length())
                                    break;
                                // 後ろをチェック prefixに対応するsuffixで回す
                                for (String suffix : this.chapterNumSuffix[i]) {
                                    if (!"".equals(suffix)) {
                                        if (noChukiLine.substring(idx).startsWith(suffix)) {
                                            idx += suffix.length();
                                            if (noChukiLine.length() == idx) {
                                                isChapter = true;
                                                break;
                                            } else if (isChapterSeparator(noChukiLine.charAt(idx))) {
                                                isChapter = true;
                                                break;
                                            }
                                        }
                                    } else {
                                        if (noChukiLine.length() == idx) {
                                            isChapter = true;
                                            break;
                                        } else if (isChapterSeparator(noChukiLine.charAt(idx))) {
                                            isChapter = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (isChapter) {
                        bookInfo.addChapterLineInfo(new ChapterLineInfo(lineNum, ChapterLineInfo.TYPE_CHAPTER_NAME, addSectionChapter, ChapterLineInfo.getLevel(ChapterLineInfo.TYPE_CHAPTER_NAME), lastEmptyLine == lineNum - 1, this.getChapterName(noRubyLine)));
                        // 次の行を連結
                        if (this.useNextLineChapterName)
                            addNextChapterName = lineNum + 1;
                        // 次の行を見出しとして利用
                        addChapterName = false;
                        // 改ページ後のChapter出力を抑止
                        addSectionChapter = false;
                    }
                }
                if (this.autoChapterNumOnly || this.autoChapterNumTitle) {
                    // 数字
                    int idx = 0;
                    while (noChukiLineLength > idx && isChapterNum(noChukiLine.charAt(idx))) idx++;
                    if (idx > 0) {
                        if (this.autoChapterNumOnly && noChukiLine.length() == idx || this.autoChapterNumTitle && noChukiLine.length() > idx && isChapterSeparator(noChukiLine.charAt(idx))) {
                            bookInfo.addChapterLineInfo(new ChapterLineInfo(lineNum, ChapterLineInfo.TYPE_CHAPTER_NUM, addSectionChapter, ChapterLineInfo.getLevel(ChapterLineInfo.TYPE_CHAPTER_NUM), lastEmptyLine == lineNum - 1, this.getChapterName(noRubyLine)));
                            // 次の行を連結
                            if (this.useNextLineChapterName)
                                addNextChapterName = lineNum + 1;
                            // 次の行を見出しとして利用しない
                            addChapterName = false;
                            // 改ページ後のChapter出力を抑止
                            addSectionChapter = false;
                        }
                    }
                }
                if (this.autoChapterNumParen || this.autoChapterNumParenTitle) {
                    // 括弧内数字のみ
                    for (int i = 0; i < this.chapterNumParenPrefix.length; i++) {
                        String prefix = this.chapterNumParenPrefix[i];
                        if (noChukiLine.startsWith(prefix)) {
                            int idx = prefix.length();
                            // 次が数字かチェック
                            while (noChukiLineLength > idx && isChapterNum(noChukiLine.charAt(idx))) idx++;
                            // 数字がなければ抽出しない
                            if (idx <= prefix.length())
                                break;
                            // 後ろをチェック
                            String suffix = this.chapterNumParenSuffix[i];
                            if (noChukiLine.substring(idx).startsWith(suffix)) {
                                idx += suffix.length();
                                if (this.autoChapterNumParen && noChukiLine.length() == idx || this.autoChapterNumParenTitle && noChukiLine.length() > idx && isChapterSeparator(noChukiLine.charAt(idx))) {
                                    bookInfo.addChapterLineInfo(new ChapterLineInfo(lineNum, ChapterLineInfo.TYPE_CHAPTER_NUM, addSectionChapter, 13, lastEmptyLine == lineNum - 1, this.getChapterName(noRubyLine)));
                                    // 次の行を連結
                                    if (this.useNextLineChapterName)
                                        addNextChapterName = lineNum + 1;
                                    // 次の行を見出しとして利用しない
                                    addChapterName = false;
                                    // 改ページ後のChapter出力を抑止
                                    addSectionChapter = false;
                                }
                            }
                        }
                    }
                }
            }
            // 改ページ後の注記以外の本文を追加
            if (this.chapterSection && addSectionChapter) {
                // 底本:は目次に出さない
                if (noRubyLine.length() > 2 && noRubyLine.charAt(0) == '底' && noRubyLine.charAt(1) == '本' && noRubyLine.charAt(2) == ':') {
                    // 改ページ後のChapter出力を抑止
                    addSectionChapter = false;
                } else {
                    // 記号のみの行は無視して次の行へ
                    String name = this.getChapterName(noRubyLine);
                    if (name.replaceAll("◇|◆|□|■|▽|▼|☆|★|*|+|×|†| ", "").length() > 0) {
                        bookInfo.addChapterLineInfo(new ChapterLineInfo(lineNum, ChapterLineInfo.TYPE_PAGEBREAK, true, 1, lastEmptyLine == lineNum - 1, name));
                        if (this.useNextLineChapterName)
                            addNextChapterName = lineNum + 1;
                        // 改ページ後のChapter出力を抑止
                        addSectionChapter = false;
                    }
                }
            }
            // 見出しの次の行&見出しでない
            if (addNextChapterName == lineNum && bookInfo.getChapterLineInfo(lineNum) == null) {
                // 見出しの次の行を繋げる
                String name = this.getChapterName(noRubyLine);
                if (name.length() > 0) {
                    ChapterLineInfo info = bookInfo.getChapterLineInfo(lineNum - 1);
                    if (info != null)
                        info.joinChapterName(name);
                }
                addNextChapterName = -1;
            }
            // コメント行の後はタイトル取得はしない
            if (!firstCommentStarted) {
                String replaced = CharUtils.getChapterName(noRubyLine, 0);
                if (firstLineStart == -1) {
                    // 文字の行が来たら先頭行開始
                    if (replaced.length() > 0) {
                        firstLineStart = this.lineNum;
                        firstLines[0] = line;
                    }
                } else {
                    // 改ページで終了
                    if (isPageBreakLine(noRubyLine))
                        firstCommentStarted = true;
                    if (this.lineNum - firstLineStart > firstLines.length - 1) {
                        firstCommentStarted = true;
                    } else if (replaced.length() > 0) {
                        firstLines[this.lineNum - firstLineStart] = line;
                    }
                }
            }
            // 前の2行を保存
            preLines[1] = preLines[0];
            preLines[0] = noRubyLine;
        }
        // 行数設定
        bookInfo.totalLineNum = lineNum;
        if (inComment) {
            LogAppender.error(commentLineStart, "コメントが閉じていません");
        }
        // 表題と著者を先頭行から設定
        bookInfo.setMetaInfo(titleType, pubFirst, firstLines, firstLineStart, firstCommentLineNum);
        // タイトルのChapter追加
        if (bookInfo.titleLine > -1) {
            String name = this.getChapterName(bookInfo.title);
            ChapterLineInfo chapterLineInfo = bookInfo.getChapterLineInfo(bookInfo.titleLine);
            if (chapterLineInfo == null)
                bookInfo.addChapterLineInfo(new ChapterLineInfo(bookInfo.titleLine, ChapterLineInfo.TYPE_TITLE, true, 0, false, name));
            else {
                chapterLineInfo.type = ChapterLineInfo.TYPE_TITLE;
                chapterLineInfo.level = 0;
            }
            // 1行目がタイトルでなければ除外
            if (bookInfo.titleLine > 0) {
                for (int i = bookInfo.titleLine - 1; i >= 0; i--) bookInfo.removeChapterLineInfo(i);
            }
        }
        if (bookInfo.orgTitleLine > 0)
            bookInfo.removeChapterLineInfo(bookInfo.orgTitleLine);
        if (bookInfo.subTitleLine > 0)
            bookInfo.removeChapterLineInfo(bookInfo.subTitleLine);
        if (bookInfo.subOrgTitleLine > 0)
            bookInfo.removeChapterLineInfo(bookInfo.subOrgTitleLine);
        // 前後2行前と2行後に3つ以上に抽出した見出しがある場合連続する見出しを除去
        if (this.excludeSeqencialChapter)
            bookInfo.excludeTocChapter();
        return bookInfo;
    } catch (Exception e) {
        e.printStackTrace();
        LogAppender.error(lineNum, "");
        throw e;
    }
}
Also used : Matcher(java.util.regex.Matcher) BookInfo(com.github.hmdev.info.BookInfo) ChapterLineInfo(com.github.hmdev.info.ChapterLineInfo) ImageInfo(com.github.hmdev.info.ImageInfo) IOException(java.io.IOException)

Example 5 with ImageInfo

use of com.github.hmdev.info.ImageInfo in project AozoraEpub3 by hmdev.

the class ImageInfoReader method loadRarImageInfos.

/**
 * rar内の画像情報をすべて読み込み
 */
public void loadRarImageInfos(File srcFile, boolean addFileName) throws IOException, RarException {
    Archive archive = new Archive(srcFile);
    try {
        int idx = 0;
        for (FileHeader fileHeader : archive.getFileHeaders()) {
            if (idx++ % 10 == 0)
                LogAppender.append(".");
            if (!fileHeader.isDirectory()) {
                String entryName = fileHeader.getFileNameW();
                if (entryName.length() == 0)
                    entryName = fileHeader.getFileNameString();
                entryName = entryName.replace('\\', '/');
                String lowerName = entryName.toLowerCase();
                if (lowerName.endsWith(".png") || lowerName.endsWith(".jpg") || lowerName.endsWith(".jpeg") || lowerName.endsWith(".gif")) {
                    ImageInfo imageInfo = null;
                    InputStream is = null;
                    try {
                        // 読めない場合があるので一旦バイト配列に読み込み
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        archive.extractFile(fileHeader, baos);
                        baos.close();
                        is = new ByteArrayInputStream(baos.toByteArray());
                        imageInfo = ImageInfo.getImageInfo(is);
                        if (imageInfo != null) {
                            this.imageFileInfos.put(entryName, imageInfo);
                            if (addFileName)
                                this.addImageFileName(entryName);
                        } else {
                            LogAppender.println();
                            LogAppender.error("画像が読み込めませんでした: " + entryName);
                        }
                    } catch (Exception e) {
                        LogAppender.println();
                        LogAppender.error("画像が読み込めませんでした: " + entryName);
                        e.printStackTrace();
                    } finally {
                        if (is != null)
                            is.close();
                    }
                }
            }
        }
    } finally {
        LogAppender.println();
        archive.close();
    }
}
Also used : Archive(com.github.junrar.Archive) ByteArrayInputStream(java.io.ByteArrayInputStream) BufferedInputStream(java.io.BufferedInputStream) FileInputStream(java.io.FileInputStream) ZipArchiveInputStream(org.apache.commons.compress.archivers.zip.ZipArchiveInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ImageInfo(com.github.hmdev.info.ImageInfo) FileHeader(com.github.junrar.rarfile.FileHeader) IOException(java.io.IOException) RarException(com.github.junrar.exception.RarException)

Aggregations

ImageInfo (com.github.hmdev.info.ImageInfo)11 IOException (java.io.IOException)7 ZipArchiveEntry (org.apache.commons.compress.archivers.zip.ZipArchiveEntry)5 BufferedInputStream (java.io.BufferedInputStream)4 SectionInfo (com.github.hmdev.info.SectionInfo)3 RarException (com.github.junrar.exception.RarException)3 BufferedWriter (java.io.BufferedWriter)3 ByteArrayInputStream (java.io.ByteArrayInputStream)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3 FileInputStream (java.io.FileInputStream)3 OutputStreamWriter (java.io.OutputStreamWriter)3 ZipArchiveInputStream (org.apache.commons.compress.archivers.zip.ZipArchiveInputStream)3 ChapterLineInfo (com.github.hmdev.info.ChapterLineInfo)2 Archive (com.github.junrar.Archive)2 FileHeader (com.github.junrar.rarfile.FileHeader)2 InputStream (java.io.InputStream)2 ArchiveEntry (org.apache.commons.compress.archivers.ArchiveEntry)2 BookInfo (com.github.hmdev.info.BookInfo)1 ChapterInfo (com.github.hmdev.info.ChapterInfo)1 GaijiInfo (com.github.hmdev.info.GaijiInfo)1