wmjordan / PDFPatcher

PDF补丁丁——PDF工具箱,可以编辑书签、剪裁旋转页面、解除限制、提取或合并文档,探查文档结构,提取图片、转成图片等等
https://pdfpatcher.cnblogs.com/
9.21k stars 1.26k forks source link

能不能提供64位的PDF补丁丁呢? #163

Open Charltsing opened 1 year ago

Charltsing commented 1 year ago

现在电脑文件都挺大的,PDF补丁丁是否支持64位?

wmjordan commented 1 year ago

应该有可能,只是所有用 C 写的库都要重新编译。 等正式版发布了之后,下个版本将转到64位平台。

Charltsing commented 1 year ago

C#可以支持原生库的Anycpu,只要给原生库的API做个包装,类似这样

代码: `[SuppressUnmanagedCodeSecurity] //调用非托管代码时执行的堆栈遍视在运行时被省略,从而大幅节省性能。 internal sealed class JBIG2EncNativeMethods {

    [DllImport("JBig2losslessEnc-x86.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, EntryPoint = "jbig2_vernumber")]
    private static extern int JBIG2EncodeVerNum_x86();
    [DllImport("JBig2losslessEnc-x64.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, EntryPoint = "jbig2_vernumber")]
    private static extern int JBIG2EncodeVerNum_x64();

    [DllImport("JBig2losslessEnc-x86.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, EntryPoint = "jbig2_version")]
    private static extern IntPtr JBIG2EncodeVer_x86();
    [DllImport("JBig2losslessEnc-x64.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, EntryPoint = "jbig2_version")]
    private static extern IntPtr JBIG2EncodeVer_x64();
    public static int JBIG2EncodeVer(out string Ver)
    {
        Ver = string.Empty;
        int vernum;
        if (IntPtr.Size == 4)
            vernum = JBIG2EncodeVerNum_x86();
        else
            vernum = JBIG2EncodeVerNum_x64();

        IntPtr p;
        if (IntPtr.Size == 4)
            p = JBIG2EncodeVer_x86();
        else
            p = JBIG2EncodeVer_x64();

        if (p!=IntPtr.Zero) Ver = Marshal.PtrToStringAnsi(p);

        return vernum;
    }

    [DllImport("JBig2losslessEnc-x86.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "jbig2_encode")]
    private static extern IntPtr Encode_x86(int width, int height, int stride, bool zeroIsWhite, IntPtr data, ref int length);

    [DllImport("JBig2losslessEnc-x64.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "jbig2_encode")]
    private static extern IntPtr Encode_x64(int width, int height, int stride, bool zeroIsWhite, IntPtr data, ref int length);
    public static IntPtr Encode(int width, int height, int stride, bool zeroIsWhite, IntPtr data, ref int length)
    {
        if (IntPtr.Size == 4)
            return Encode_x86(width, height, stride, zeroIsWhite, data, ref length);
        else
            return Encode_x64(width, height, stride, zeroIsWhite, data, ref length);            
    }

    [DllImport("JBig2losslessEnc-x86.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "release")]
    private static extern IntPtr Release_x86(IntPtr data);
    [DllImport("JBig2losslessEnc-x64.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "release")]
    private static extern IntPtr Release_x64(IntPtr data);
    public static IntPtr Release(IntPtr data)
    {
        if (IntPtr.Size == 4)
            return Release_x86(data);
        else
            return Release_x64(data);
    }
}`
Charltsing commented 1 year ago

C#可以支持原生库的Anycpu,只要给原生库的API做个包装,类似这样 `[SuppressUnmanagedCodeSecurity] //调用非托管代码时执行的堆栈遍视在运行时被省略,从而大幅节省性能。 internal sealed class JBIG2EncNativeMethods { //https://hub.njuu.cf/AndreyAkinshin/InteropDotNet 通过LoadLibrary和GetProcAddress实现。

    [DllImport("JBig2losslessEnc-x86.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, EntryPoint = "jbig2_vernumber")]
    private static extern int JBIG2EncodeVerNum_x86();
    [DllImport("JBig2losslessEnc-x64.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, EntryPoint = "jbig2_vernumber")]
    private static extern int JBIG2EncodeVerNum_x64();

    [DllImport("JBig2losslessEnc-x86.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, EntryPoint = "jbig2_version")]
    private static extern IntPtr JBIG2EncodeVer_x86();
    [DllImport("JBig2losslessEnc-x64.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, EntryPoint = "jbig2_version")]
    private static extern IntPtr JBIG2EncodeVer_x64();
    public static int JBIG2EncodeVer(out string Ver)
    {
        Ver = string.Empty;
        int vernum;
        if (IntPtr.Size == 4)
            vernum = JBIG2EncodeVerNum_x86();
        else
            vernum = JBIG2EncodeVerNum_x64();

        IntPtr p;
        if (IntPtr.Size == 4)
            p = JBIG2EncodeVer_x86();
        else
            p = JBIG2EncodeVer_x64();

        if (p!=IntPtr.Zero) Ver = Marshal.PtrToStringAnsi(p);

        return vernum;
    }

    [DllImport("JBig2losslessEnc-x86.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "jbig2_encode")]
    private static extern IntPtr Encode_x86(int width, int height, int stride, bool zeroIsWhite, IntPtr data, ref int length);

    [DllImport("JBig2losslessEnc-x64.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "jbig2_encode")]
    private static extern IntPtr Encode_x64(int width, int height, int stride, bool zeroIsWhite, IntPtr data, ref int length);
    public static IntPtr Encode(int width, int height, int stride, bool zeroIsWhite, IntPtr data, ref int length)
    {
        if (IntPtr.Size == 4)
            return Encode_x86(width, height, stride, zeroIsWhite, data, ref length);
        else
            return Encode_x64(width, height, stride, zeroIsWhite, data, ref length);            
    }

    [DllImport("JBig2losslessEnc-x86.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "release")]
    private static extern IntPtr Release_x86(IntPtr data);
    [DllImport("JBig2losslessEnc-x64.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "release")]
    private static extern IntPtr Release_x64(IntPtr data);
    public static IntPtr Release(IntPtr data)
    {
        if (IntPtr.Size == 4)
            return Release_x86(data);
        else
            return Release_x64(data);
    }
}`
Charltsing commented 1 month ago

我现在是采用内存加载的方式来实现anycpu的c库。 参见https://github.com/wwh1004/MemoryModule

wmjordan commented 1 month ago

加载库不是什么问题。主要麻烦的工作是:

  1. 重新编译所有依赖的C库为 64 位,FreeImage 和 MuPDF 都已经有 64 位的了,还差一个 JBIG2 编码库。
  2. MODI 只有 32 位,要做一个 32 位的程序,专门调用 MODI,在主程序使用跨进程通信的方式调用这个程序,获取识别结果。

时间有限,目前没有空闲做这两项工作。

Charltsing commented 1 month ago

JBIG2编译为64位没什么障碍,我这都有现成的。 MODI早已经过时了,我之前试过调用OneNote和飞桨,都各有问题。现在我的软件都换成在线接口了,识别率杠杠的。

目前桌面版软件没什么方便的本机OCR库。也许你可以考虑试试UWP下的库,这个识别率要高一些,需要安装UWP运行库 参考源代码 https://www.52pojie.cn/thread-1967800-1-1.html

顺便说一下,我觉得没必要在补丁丁里面集成OCR功能,这不应该是补丁丁的工作。