ImageProcessing-ElectronicPublications / photoquick

Light-weight image viewer with crop,resize,collage, photogrid and filters
GNU General Public License v3.0
4 stars 0 forks source link

Export to PDF? #15

Closed zvezdochiot closed 4 years ago

zvezdochiot commented 4 years ago

:warning: "Export to PDF" not works.

photoquick -> Open page0001.jpg -> Export to PDF -> page0001.pdf

Use GhostScript:

ps2pdf page0001.pdf page0001.ps.pdf 
   **** Unknown operator: '0,0000'
   **** Unknown operator: '0,0000'
   **** Error reading a content stream. The page may be incomplete.
   **** File did not complete the page properly and may be damaged.
   **** Warning: File has unbalanced q/Q operators (too many q's)

   **** This file had errors that were repaired or ignored.
   **** The file was produced by: 
   **** >>>> PDF Writer by Arindam <<<<
   **** Please notify the author of the software that produced this
   **** file that it does not conform to Adobe's published PDF
   **** specification.

Output:

340 page0001.pdf
  4 page0001.ps.pdf

:question: This is due to the use of a comma in the system instead of a period for the decimal separator. Is it possible to make it independent of the system settings?

zvezdochiot commented 4 years ago

:information_source: Additional Information: https://github.com/ImageProcessing-ElectronicPublications/photoquick/blob/550b518d93321ee0ab01d0435639377156b50253/src/pdfwriter.cpp#L219-L249

page0001.pdf:

5 0 obj 
<<
/Length 68
>>
stream
q 1 0 0 1 0,0000 0,0000 cm
595,0000 0 0 834,0000 0 0 cm
 /img0 Do Q

endstream 
endobj 

instead:

5 0 obj 
<<
/Length 68
>>
stream
q 1 0 0 1 0.0000 0.0000 cm
595.0000 0 0 834.0000 0 0 cm
 /img0 Do Q

endstream 
endobj 
ksharindam commented 4 years ago

This is due to the use of a comma in the system instead of a period for the decimal separator. Is it possible to make it independent of the system settings?

Try adding this in main.cpp #include <clocale> And first line of main() function... setlocale(LC_NUMERIC, "C");

And tell me the results

zvezdochiot commented 4 years ago

Hi @ksharindam .

setlocale() didn't help. In PDF in 5 0 obj is still commas instead of dots.

:question: Maybe use trans_str.replace(trans_str.find(","),1,".");?

:question: Maybe patch pdfwriter.cpp?:

std::string imgMatrix(float x, float y, float w, float h, int rotation)
{
...
    while (trans_str.find(",") != std::string::npos)
    {
        trans_str.replace(trans_str.find(","),1,".");
    }
    std::string matrix = format("%s %s cm\n", rot_str.c_str(), trans_str.c_str()); // translate and then rotate
    if (rot==90 or rot==270) {
        float tmp = w;
        w = h;
        h = tmp;
    }
    trans_str = format("%.4f 0 0 %.4f 0 0 cm\n" ,w, h); // finally scale image
    while (trans_str.find(",") != std::string::npos)
    {
        trans_str.replace(trans_str.find(","),1,".");
    }
    matrix += trans_str;
    return matrix;
}

Patch work.

zvezdochiot commented 4 years ago

Hi @ksharindam .

I found a way to use std::locale in C ++:

Patch pdfwriter.cpp:

#include "pdfwriter.h"
#include <clocale>

PdfWriter:: PdfWriter()
{
    std::locale::global(std::locale("C"));
    version = "1.4";
    producer = "PDF Writer by Arindam";
    header = format("%%PDF-%s\n", version.c_str());
}
...
std::string imgMatrix(float x, float y, float w, float h, int rotation)
{
    int rot = rotation%360;
    std::string trans_str, rot_str;
    switch (rot) {
        case 0:
            rot_str = "1 0 0 1";
            break;
        case 90:
            y += h;
            rot_str = "0 -1 1 0";
            break;
        case 180:
            x += w;
            y += h;
            rot_str = "-1 0 0 -1";
            break;
        case 270:
            x += w;
            rot_str = "0 1 -1 0";
            break;
    }
    trans_str = format("%.4f %.4f", x, y);
    std::string matrix = format("%s %s cm\n", rot_str.c_str(), trans_str.c_str()); // translate and then rotate
    if (rot==90 or rot==270) {
        w += h;
        h = w - h;
        w -= h;
    }
    matrix += format("%.4f 0 0 %.4f 0 0 cm\n" ,w, h);      // finally scale image
    return matrix;
}

:question: Maybe add to the options A4, A5 options 150dpi, 300dpi, 600dpi?

ksharindam commented 4 years ago

what is your locale settings?

zvezdochiot commented 4 years ago

Hi @ksharindam .

$ locale
LANG=ru_RU.UTF-8
LANGUAGE=
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=
ksharindam commented 4 years ago

i will set my system settings to this locale and check which cleaner method works

zvezdochiot commented 4 years ago

:+1: Ok.

ksharindam commented 4 years ago

I have checked. putting setlocale(LC_NUMERIC, "C"); at the first line of PdfWriter constructor works fine. but putting this line at be beginning of main() does not work. check it now. and let me know.

zvezdochiot commented 4 years ago

Hi @ksharindam .

Yes, patch work: pdfwriter.cpp:

#include "pdfwriter.h"
#include <clocale>

PdfWriter:: PdfWriter()
{
    setlocale(LC_NUMERIC, "C");
    version = "1.4";
    producer = "PDF Writer by Arindam";
    header = format("%%PDF-%s\n", version.c_str());
}
...
ksharindam commented 4 years ago

ok, I am uploading this.

ksharindam commented 4 years ago

Maybe add to the options A4, A5 options 150dpi, 300dpi, 600dpi?

Hi @zvezdochiot It is a good idea, as it will be useful for images scanned with a scanner, where dpi is already known. When i will have time, i will add this.