Ответы пользователя по тегу Java
  • Как использовать изображение в качестве символа списка?

    @iText_A
    Посмотрите пример ListWithImageAsBullet. В примере мы берем изображение лампочки и используем его в качестве маркера списка:
    Image image = Image.getInstance(IMG);
    image.scaleAbsolute(12, 12);
    image.setScaleToFitHeight(false);
    List list = new List();
    list.setListSymbol(new Chunk(Image.getInstance(image), 0, 0));
    list.add("Hello World");
    list.add("This is a list item with a lot of text. It will certainly take more than one line. This shows that the list item is indented and that the image is used as bullet.");
    list.add("This is a test");
    document.add(list);


    Результат выглядит следующим образом:
    5d09fbb564ad2967574669.png

    Изображение в качестве маркера списка
    Ответ написан
    Комментировать
  • Как создать двухмерный штрихкод в виде векторного изображения?

    @iText_A
    Посмотрите пример BarcodePlacement. Здесь мы создаем три штрихкода PDF417:
    Image img = createBarcode(1, 1, pdfDoc);
    doc.add(new Paragraph(String.format("This barcode measures %s by %s user units",
        img.getImageScaledWidth(), img.getImageScaledHeight())));
    doc.add(img);
    img = createBarcode(3, 3, pdfDoc);
    doc.add(new Paragraph(String.format("This barcode measures %s by %s user units",
        img.getImageScaledWidth(), img.getImageScaledHeight())));
    doc.add(img);
    img = createBarcode(3, 1, pdfDoc);
    doc.add(new Paragraph(String.format("This barcode measures %s by %s user units",
        img.getImageScaledWidth(), img.getImageScaledHeight())));
    doc.add(img);

    Результат выглядит следующим образом:
    5d087aa1295b9835771594.png
    Штрихкоды
    Так выглядит один из штрихкодов внутри:
    5d087ac3eccf0509071833.png
    Векторные данные
    Я добавляю вид изнутри, чтобы показать, что двухмерный штрихкод не добавляется как растровое изображение (как в вашем примере). Это векторное изображение, состоящее из группы маленьких прямоугольников. Вы можете проверить это самостоятельно в файле barcode_placement.pdf
    ОбъектImageне должен вас запутать. Если вы посмотрите на метод createBarcode(), то увидите, что Image в действительности является векторным изображением:
    public Image createBarcode(float mw, float mh, PdfDocument pdfDoc) {
        BarcodePDF417 barcode = new BarcodePDF417();
        barcode.setCode("BarcodePDF417 barcode");
        return new Image(barcode.createFormXObject(Color.BLACK, pdfDoc)).scale(mw, mh);
    }

    Высота и ширина, которые передаются через метод scale(), определяют высоту и ширину маленьких прямоугольников. Во внутренней части штрихкода, можно увидеть следующее:
    0 21 3 1 re
    Это прямоугольник, у которого x = 0, y = 21, ширина — 3, а высота —1.

    Когда вы запрашиваете размер штрихкода, то получаете число необходимых прямоугольников. Размеры штрихкода будут рассчитываться следующим образом:
    Rectangle size = barcode.getBarcodeSize();
    float width = mw * size.getWidth();
    float height = mh * size.getHeight();

    Вы допускаете, что значение size (размер в единицах пользователя) верно, только если mw и mh равняются 1.

    Я использую значения для создания примера PdfFormXObject и переношу его в Image. Затем я могу добавить Image к документу, как и любое другое изображение. Основное отличие этого изображения от обычных заключается в том, что оно векторное.
    Ответ написан
    Комментировать
  • Как превратить фоновое изображение в водяной знак, изменив прозрачность?

    @iText_A
    Посмотрите пример BackgroundTransparent. Это вариант примера BackgroundImage

    В своем коде вы добавляете Image к экземпляру Document. В этом нет ничего плохого, но если вы хотите сделать изображение прозрачным, нужно создать мягкую маску. Это нетрудно, но есть и более простой способ сделать фон прозрачным: добавьте изображение прямо к содержимому, а затем определите прозрачность с помощью PdfExtGState:

    PdfCanvas canvas = new PdfCanvas(pdfDoc.addNewPage());
    ImageData image = ImageDataFactory.create(imgSrc);
    canvas.saveState();
    PdfExtGState state = new PdfExtGState();
    state.setFillOpacity(0.6f);
    canvas.setExtGState(state);
    canvas.addImage(image, 0, 0, pageSize.getWidth(), false);

    Вы можете сравнить результаты примеров выше и увидеть разницу.
    Мой пример написан на Java, но его легко изменить для C#.
    Ответ написан
    Комментировать
  • Как добавить карту с указателем в PDF-файл?

    @iText_A
    Что вы имеете в виду под «картой с указателем, чтобы пользователь знал, где находится изначальная точка»? Если в PDF-файле есть карта, можно добавить аннотацию в виде стрелки. Вам нужно именно это?
    Приведу два примера.
    Пример 1: добавление настраиваемой формы в качестве дополнительного содержимого поверх карты
    Этот вариант продемонстрирован в примере AddPointer:
    PdfCanvas canvas = new PdfCanvas(pdfDoc.getFirstPage());
    canvas.setStrokeColor(Color.RED)
            .setLineWidth(3)
            .moveTo(220, 330)
            .lineTo(240, 370)
            .arc(200, 350, 240, 390, 0, (float) 180)
            .lineTo(220, 330)
            .closePathStroke()
            .setFillColor(Color.RED)
            .circle(220, 370, 10)
            .fill();

    Если известны координаты, то можно нарисовать из линий и кривых красный указатель, как на картинке ниже (красный указатель возле Cambridge Innovation Center):
    5cf4c9bc2298e260188495.png
    Карта с указателем

    Пример 2: добавление строковой аннотации поверх карты
    Этот вариант продемонстрирован в примере AddPointerAnnotation:
    Rectangle rect = new Rectangle(220, 350, 255, 245);
    PdfLineAnnotation lineAnnotation = new PdfLineAnnotation(rect, new float[]{225, 355, 470, 590});
    lineAnnotation.setTitle(new PdfString("You are here:"));
    lineAnnotation.setContents("Cambridge Innovation Center");
    lineAnnotation.setColor(Color.RED);
    lineAnnotation.setFlag(PdfAnnotation.PRINT);
     
    PdfDictionary borderStyle = new PdfDictionary();
    borderStyle.put(PdfName.S, PdfName.S);
    borderStyle.put(PdfName.W, new PdfNumber(5));
    lineAnnotation.setBorderStyle(borderStyle);
     
    PdfArray le = new PdfArray();
    le.add(new PdfName("OpenArrow"));
    le.add(new PdfName("None"));
    lineAnnotation.put(new PdfName("LE"), le);
    lineAnnotation.put(new PdfName("IT"), new PdfName("LineArrow"));
     
    pdfDoc.getFirstPage().addAnnotation(lineAnnotation);

    В результате получается аннотация (она является частью не настоящего содержимого, а интерактивного слоя, накладываемого поверх настоящего содержимого):
    5cf4ca5a5edc9578161343.png
    Карта с аннотацией

    Слой интерактивный: когда пользователь нажимает на аннотацию, появляется дополнительная информация:
    5cf4ca951dde8997489097.png
    Карта с открытой аннотацией
    Ответ написан
    Комментировать
  • Почему не применяется шрифт при создании PDF-документа?

    @iText_A
    По умолчанию FontProgramFactory (FontFactory в iText 5) знает только шрифты типа 1, а шрифт "garamond bold" не входит в этот список, поэтому используется Helvetica (Helvetica — шрифт по умолчанию в iText).
    Можно «научить» FontProgramFactory, как находить другие шрифты, зарегистрировав их. Можно попробовать следующее:
    FontProgramFactory.registerSystemFontDirectories();

    Но это очень затратная операция, так как здесь iText ищет в вашей операционной системе файлы шрифтов в разных каталогах (например, в C:/Windows/Fonts). Это может занять несколько секунд, и на выходе получится намного больше шрифтов, чем необходимо (возможно, что нужный шрифт так и не будет зарегистрирован).

    Лучше регистрировать шрифты следующим образом.
    FontProgramFactory.registerFont("c:/windows/fonts/garabd.ttf", "garamond bold");

    Мы сообщаем iText, где найти файл .ttf ("c:/windows/fonts/garabd.ttf") и определяем псевдоним для нужного шрифта («garamond bold»). Теперь, когда название шрифта зарегистрировано, его можно использовать:
    PdfFont myBoldFont = PdfFontFactory.createRegisteredFont("garamond bold");
    Ответ написан
    Комментировать
  • ITEXT7 создает pdf файл с Exception “Pdf indirect object belongs to other PDF document. Copy object to current pdf document.”?

    @iText_A
    Я столкнулся с такой же проблемой (у меня ушли часы, чтобы разобраться в том, что я делал не так). Как оказалось, вы можете использовать конкретный экземпляр PdfFont только для одного документа. Как только вы используете экземпляр PdfFont в документе, он привязывается к нему, и вы больше не можете использовать его в другом документе.

    Например:
    class ThisGoesWrong {
    
        protected PdfFont font;
    
        public ThisGoesWrong() {
            font = PdfFontFactory.createFont(...);
        }
    
        public void createPdf() {
            ...
            Paragraph p = new Paragraph("test").setFont(font);
            document.add(p);
            ...
        }
    }

    Класс ThisGoesWrong создает правильный PDF при первом вызове createPdf(), но показывает exception как у вас, когда вы вызываете его повторно.

    Я нашел такое решение проблемы:
    class ThisWorksOK {
    
        public ThisWorksOK() {
        }
    
        public void createPdf() {
            ...
            PdfFont font = PdfFontFactory.createFont(...);
            Paragraph p = new Paragraph("test").setFont(font);
            document.add(p);
            ...
        }
    }
    Ответ написан
    Комментировать
  • ITEXT7: Как создать абзац смешивая различные шрифты?

    @iText_A
    Пожалуйста ознакомьтесь с документацией, особое внимание уделите разделу iText7: строительные блоки "Глава 1: Знакомство с .... Из этой главы вы узнаете, что используя iText7, намного проще переключать шрифты, потому как вы можете работать со стандартными шрифтами и их размерами, вы можете определять и повторно использовать Style объекты и т.д.

    Пример:
    PdfFont font = PdfFontFactory.createFont(FontConstants.TIMES_ROMAN);
    normal.setFont(font).setFontSize(14);
    Style code = new Style();
    PdfFont monospace = PdfFontFactory.createFont(FontConstants.COURIER);
    code.setFont(monospace).setFontColor(Color.RED)
        .setBackgroundColor(Color.LIGHT_GRAY);
    Paragraph p = new Paragraph();
    p.add(new Text("The Strange Case of ").addStyle(normal));
    p.add(new Text("Dr. Jekyll").addStyle(code));
    p.add(new Text(" and ").addStyle(normal));
    p.add(new Text("Mr. Hyde").addStyle(code));
    p.add(new Text(".").addStyle(normal));
    document.add(p);


    для начала мы определим Style, назовем его normal и укажем для него шрифт Times-Roman размером в 14pt. После этого мы определим Style, который назовем code и зададим ему шрифт красного цвета Courier, размером в 12pt с серым фоном. После этого мы создадим Paragraph, с помощью Text объектов, которые задействуют эти стили.

    Обратите внимание, что вы можете цеплять add()комментарии, как это сделано в следующем примере:

    Text title1 = new Text("The Strange Case of ").setFontSize(12);
    Text title2 = new Text("Dr. Jekyll and Mr. Hyde").setFontSize(16);
    Text author = new Text("Robert Louis Stevenson");
    Paragraph p = new Paragraph().setFontSize(8)
        .add(title1).add(title2).add(" by ").add(author);
    document.add(p);


    «Установим размер шрифта для только что созданного Paragraph в 8pt. Этот размер шрифта будет наследоваться всеми объектами, добавленными в Paragraph, если только объекты не переопределяют этот размер по умолчанию. Это относится к title1, для которого мы определили размер шрифта в 12pt и для title2, для которого мы определили размер шрифта в 16pt. Содержимое, добавленное как String (" by "), и содержимое, добавленное как Textобъект, для которого не был определен размер шрифта, наследует размер шрифта в 8pt из Paragraph, в который они добавлены.»

    Это выдержка из официального руководства, и я надеюсь этого будет достаточно для StackOverflow, где ответы в виде одной только ссылки не приветствуются. Однако, я считаю, что это правило не должно приводить к копипасту целой главы мануала.
    Ответ написан
    Комментировать