65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 中的 CBR/CBZ 漫画

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.56/5 (12投票s)

2008 年 7 月 28 日

CPOL

7分钟阅读

viewsIcon

107815

downloadIcon

1740

在 C# 中与 CBZ/CBR 漫画书进行交互。

CBR-Index

引言

虽然漫画书很容易被一些人视为幼稚的消遣,但在我看来,它们就像我小时候一样。对我来说,这些是激动、道德和青少年赋权的故事,可以激发对艺术、叙事和人性的兴趣。20 世纪的大部分漫画书都以实体(书本)形式呈现,而从书中获得的乐趣一部分来自于实体本身。然而,随着技术的发展,所有形式的媒体都在以数字格式重新塑造自己。

漫画书媒介向数字创作和发行转变也不例外。与任何令人兴奋的新数字媒介一样,程序员都寻求与定义该媒介的标准进行交互、操作和自动化。虽然尚未出现权威联盟来定义法规和协议,但通过顺序图像查看器,漫画领域提供了几种(免费)产品。

本文将演示与当今漫画应用程序交互的简单方法,更重要的是,如何将您的纸质漫画书转换成可以有序存储在光盘 (CD) 或数字多功能光盘 (DVD) 上的数字图书馆。此外,我将解释如何增强我的基本演示应用程序以添加对您重要的功能。

背景

大约两年前,当我搬进新家时,我有幸(或不幸)整理童年遗物和未使用的物品,以确定哪些该扔,哪些该留。在此过程中,我偶然发现了我的童年漫画收藏。翻阅那些装满《蜘蛛侠》、《X战警》、《The Maxx》、《再生侠》等漫画的盒子,我开始回忆起这些故事在我小时候对我的生活产生的影响。我实在无法将这些书扔进垃圾桶。然而,如果我让它们在车库的箱子里腐烂,它们肯定会因为潮湿和不同的冷热程度而被毁坏。

此时,我决定将数字化和整理这些珍贵的美国文学作品作为首要任务。

扫描您的书籍

这项工作的大部分在于书籍的扫描。我认为 Marvel、DC 和其他公司已经以某种数字格式提供他们的书籍,但我并不关心新漫画。我的首要任务是保存我已有的书籍,我不愿意重新购买任何东西。

我耐心地逐一扫描了我的惠普 OfficeJet L7650 上的每一本书,分辨率为 300 DPI。每页完成后,我适当地裁剪页面,以确保页面尽可能干净。每次扫描后,我将图像加载到 Adobe Photoshop CS3 中,如果页面太亮,则添加叠加层以提亮图像,然后将其缩小到 100-200 DPI 之间,这使得图像非常清晰。

我为我将要扫描的每本漫画创建了一个单独的文件夹,并且**我以顺序的方式命名了每个扫描的图像**。封面会有一个文件名,确保它始终在开头,例如 *01a.jpg*,下一页将是 *01.jpg*、*02.jpg*、*03.jpg* 等。这非常**重要**,以确保稍后演示的软件能够正常工作。每本漫画书完成后,我使用 WinZip 将所有文件压缩成一个存档。最后一步是创建一个 NFO 文件并将存档重命名为 * .cbz*。

CBZ 和 CBR 格式

很久以前我开始这个项目时,我以为编写软件会是容易的部分。我确信这个行业有一个我可以参考 IEEE 文档和 API 的标准。不幸的是,结果完全不是这样。据我所知,有两种相互竞争的格式,而且这两种格式都根本不特定于漫画!

目前有两种标准格式:**Zip 存档漫画书 (CBZ)** 和 **漫画书阅读器 (CBR)**。据我所知,没有哪种特定格式比另一种提供更多好处,只会让消费者感到困惑。CBZ 格式只是一个重命名的 ZIP 存档,而 CBR 格式是一个重命名的 RAR 存档。就我个人而言,我更喜欢 CBZ,因为每个人都有一个可以用来解压存档的 zip 压缩器,而有些人可能没有像 WinRaR 这样的 RAR 应用程序,但这只是个人偏好问题。

创建 CBZ/CBR 存档时,关键是其中包含的所有文件都必须按顺序命名,封面是存档中的第一个文件。大多数存档器还包括一个 NFO 文件,这是一个纯文本文件,其中包含有关书籍的详细信息。通常,封面上的所有数据,如铅笔画师、墨线画师、编剧、编辑等,都包含在 NFO 中。您的漫画阅读器应用程序每次打开一本书时都会显示此 NFO。

漫画阅读应用程序

这个项目的目标不是取代现有的漫画阅读器(尽管如果您愿意,可以轻松做到),而是为启动它们或与它们交互提供一个更简洁的用户界面。市面上有许多顺序图像查看器,但我个人最喜欢 Windows 上的 CDisplayComicRackComicReader X。对于 Unix/Linux 操作系统,有 Comix,它是一个很棒的 GTK 漫画阅读器。

所有这些阅读器都功能齐全,尽管像 ComicRack 这样的阅读器还额外提供了排序、分组书籍和流派等功能。上述任何阅读器都将满足我们项目的需求。请务必在玩演示应用程序之前,将 CBR 和 CBZ 扩展名注册到其中一个阅读器,因为我们将从我们的应用程序中启动漫画文件。

我们项目目标

我这个项目的最终目标很简单,我希望有一种方法可以将我的漫画书存档到 CD 或 DVD 上,并且我希望有一种简单的方法来查看每本漫画,并看到封面、书籍大小和页数等基本细节。如果没有某种界面,您必须逐一打开每本漫画才能找到您想看的那一本。

这个启动器应用程序需要能够轻松地从 CD/DVD 的 *autorun.inf* 设置中运行。

代码

为了实现我们所需的功能,我们基本上只需要一种解压 RAR 和 ZIP 文件的方法。ZIP 部分使用 SharpLibZip 很容易实现,但 RAR 部分更具挑战性。我尝试了各种方法,例如 UnRaRDLL 和 *unrar.exe*,但我尝试的库和实用程序并没有达到我想要的效果,所以我选择了 ChilkatDotNet2.dll(这些 RAR 实用程序是免费软件)。

一旦库问题解决,我为这个小工具构建了一个非常简单的对象模型。

用于此功能的表单除了获取与 CBR/CBZ 文件掩码匹配的文件并基于此构建后端实体之外,并没有做太多事情。

private string GetZeroImageFromArchive()
{
    string selected = lbFiles.SelectedItem.ToString().ToLower();
    if (selected.IndexOf(".cbr") > -1)
    {
        myComic = new CbrComic(string.Format("{0}\\{1}",
        scanPath, lbFiles.SelectedItem.ToString()));
    }

    if (selected.IndexOf(".cbz") > -1)
    {
        myComic = new CbzComic(string.Format("{0}\\{1}",
        scanPath, lbFiles.SelectedItem.ToString()));
    }
    
    textBox1.Text = string.Format("{0}\r\nSize: {1}MB\r\nPages: {2}", 
        myComic.FileName, myComic.FileSize, myComic.PageCount);

    if (myComic.ErrorMessage != string.Empty)
    {
        MessageBox.Show(myComic.ErrorMessage);
    }
     
    return myComic.CoverPath;
}

获取 CBZ 文件的封面

private void GenerateCover()
{
    this.ErrorMessage = string.Empty;
    
    using (ZipFile zFile = new ZipFile(File.OpenRead(FilePath)))
    {
        PageCount = (int)zFile.Count;
    }

    using (ZipInputStream s = new ZipInputStream(File.OpenRead(FilePath)))
    {
        ZipEntry theEntry;
        while ((theEntry = s.GetNextEntry()) != null)
        {
            
            string directoryName = Path.GetDirectoryName(theEntry.Name);
            string fileName = Path.GetFileName(theEntry.Name);

            // create directory if the archive has a folder at root
            if (directoryName.Length > 0)
            {
                string fDirectory = Path.GetTempPath() + directoryName;
                
                //We need to delete the directory is it's already 
                //there so we get the first entry
                if (Directory.Exists(fDirectory))
                {
                    Directory.Delete(fDirectory, true);
                }
                Directory.CreateDirectory(fDirectory);
            }

            string fullPath = Path.GetTempPath() + theEntry.Name;

            if (fileName != String.Empty && !File.Exists(fullPath))
            {
                using (FileStream streamWriter = File.Create(fullPath))
                {
                    int size = 2048;
                    byte[] data = new byte[2048];
                    while (true)
                    {
                        size = s.Read(data, 0, data.Length);
                        if (size > 0)
                        {
                            streamWriter.Write(data, 0, size);
                        }
                        else
                        {
                            break;
                        }
                    }
                    CoverPath = fullPath;
                    return; //Just return the 1st entry in the archive
                }
            }
        }
    }
}

获取 CBR 文件的封面

private void GenerateCover()
{
    this.ErrorMessage = string.Empty;
    string path = string.Empty;
    Chilkat.Rar rar = new Chilkat.Rar();
    bool success = rar.Open(FilePath);
    PageCount = (int)rar.NumEntries;

    path = Path.GetTempPath();

    if (success)
    {
        Chilkat.RarEntry entry = rar.GetEntryByIndex(0);
        if (entry.IsDirectory)
        {
            entry = rar.GetEntryByIndex(1);
            entry.Unrar(path);
        }
        else
        {
            entry.Unrar(path);
        }

        FileInfo FI = new FileInfo(string.Format("{0}\\{1}", 
                          path, entry.Filename));
        CoverPath = FI.FullName;
    }
    else
    {
        this.ErrorMessage = "There was an Error: " + rar.LastErrorText;
    }
}

运行演示

为了运行演示,您需要在 *CBR-Index.exe.config* 文件中设置一些变量。

  • banner - 标题文本。
  • scan - 包含 CBR/CBZ 文件的路径。空字符串表示工作目录。

您可以在文章顶部的屏幕截图中看到,我已将横幅值设置为 McFarlane Spiderman 系列完整版,并且扫描目录为空,因为此应用程序正在从 CDROM 运行。

在光盘介质上编译合集

为了充分利用该实用工具,我建议创建 CD 或 DVD,其中光盘的根目录填充着特定的系列,例如《恶灵骑士》、《银影侠》或其他,并且应用程序设置为自动运行。这样,每当您将漫画 CD 放入光盘托盘时,应用程序就会加载,您将拥有一个清晰的界面来浏览光盘内容。

我时间非常紧迫,所以还没有设计出管理整个光盘集合的系统,但我计划尽快完成。我还计划在应用程序中添加一个选项卡,其中将有一个列表视图,显示扫描目录中的所有封面,这样您就不必选择单个文件来查看封面。

历史

  • 08年7月28日——提交文章。
  • 08年7月30日——新增对 ComicReader X 和 ComicRack 的提及
© . All rights reserved.