UPD 30.05
Добавил параметр функции ДелатьБольшие - это позволяет ограничить установку штампа на файлы до 5Мб, если этого не сделать можно на больших входящих повесить сервак.
Письма с большими файлами можно (при необходимости) штрихкодировать вызывая функцию вручную, для этого я в меню команд Входящего документа (Форма элемента) добавил свою команду "Нанести штамп".
Добавил изменение, которое проставляет штамп только на первой странице файла. Так лучше.
Основной текст статьи:
Обязательное условие - установленный на сервере ImageMagic, Ghostscript. У меня версия ImageMagick-6.9.1-Q8, работает стабильно, как на счет других версий - не знаю.
Процедура размещена в общем модуле, обращение к ней происходит по дополнительному обработчику бизнес-события "Регистрация входящего документа".
Единственный минус, который я сейчас вижу - сильное увеличение размера файла PDF после нанесения штампа, в ситуации когда дисковое пространство стоит копейки, этот минус несущественный.
Кроме штампа я еще решил наносить штрих-код, его рисую вместе с числовым представлением на случай если придется его считать, а сканер "не возьмёт", тогда его можно будет идентифицировать по номеру кода.
Штрих-код присваивается элементу справочника - входящему документу, а не файлу, так мне кажется правильнее.
Штамп наносится только на файлы, которые помечены в карточке как "скан-копии оригинала", кроме того к версии добавляется автоматический комментарий, который указывает, что версия уже "проштампована" и не требует повторной обработки.
Текст функции привожу как есть
&НаСервере
Функция НанестиШтампНаСканКопиюОригина (ДокументСсылка, ДелатьБольшие = Ложь) Экспорт
Документ = ДокументСсылка.ПолучитьОбъект();
стрРезультат = Ложь;
если НЕ ЗначениеЗаполнено(Документ.РегистрационныйНомер) или НЕ ЗначениеЗаполнено(Документ.ДатаРегистрации) тогда
Возврат стрРезультат;
конецесли;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| Файлы.ТекущаяВерсия,
| Файлы.Ссылка КАК Файл,
| Файлы.ПометкаУдаления,
| Файлы.Зашифрован,
| Файлы.ВладелецФайла КАК ВладелецФайла,
| ISNULL(СведенияОФайлах.ЯвляетсяОригиналом, ЛОЖЬ) КАК ЯвляетсяОригиналом
|ИЗ
| Справочник.Файлы КАК Файлы
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СведенияОФайлах КАК СведенияОФайлах
| ПО (СведенияОФайлах.Файл = Файлы.Ссылка)
|ГДЕ
| Файлы.ВладелецФайла = &ВладельцыФайлов
| И Файлы.ТекущаяВерсия <> ЗНАЧЕНИЕ(Справочник.ВерсииФайлов.ПустаяСсылка)
| И выразить(Файлы.ТекущаяВерсия.Комментарий как строка(17))<> ""Вставка штрихкода""
| И НЕ Файлы.ПометкаУдаления И СведенияОФайлах.ЯвляетсяОригиналом = ИСТИНА";
Запрос.Параметры.Вставить("ВладельцыФайлов", Документ.Ссылка);
Результат = Запрос.Выполнить().Выбрать();
Пока Результат.Следующий() цикл
если ВРЕГ(Результат.Файл.ТекущаяВерсия.Расширение) <> ВРЕГ("pdf") тогда
Продолжить;
конецесли;
если ДелатьБольшие тогда
если Результат.Файл.ТекущаяВерсия.Размер > 50000000 тогда
Продолжить;
конецесли;
иначе
если Результат.Файл.ТекущаяВерсия.Размер > 5000000 тогда
Продолжить;
конецесли;
конецесли;
ТипХраненияФайла = Результат.Файл.ТекущаяВерсия.ТипХраненияФайла;
ИмяФайлаСПутем = ПолучитьИмяВременногоФайла(Результат.Файл.ТекущаяВерсия.Расширение);
Если ТипХраненияФайла = Перечисления.ТипыХраненияФайлов.ВИнформационнойБазе Тогда
ХранилищеФайла = РаботаСФайламиВызовСервера.ПолучитьХранилищеФайлаИзИнформационнойБазы(Результат.Файл.ТекущаяВерсия);
ДвоичныеДанныеФайла = ХранилищеФайла.Получить();
ДвоичныеДанныеФайла.Записать(ИмяФайлаСПутем);
Иначе
Если НЕ Результат.Файл.ТекущаяВерсия.Том.Пустая() Тогда
ИмяФайлаСПутемВТоме = ФайловыеФункции.ПолныйПутьТома(Результат.Файл.ТекущаяВерсия.Том) + Результат.Файл.ТекущаяВерсия.ПутьКФайлу;
КопироватьФайл(ИмяФайлаСПутемВТоме, ИмяФайлаСПутем);
Файл = Новый Файл(ИмяФайлаСПутем);
Файл.УстановитьТолькоЧтение(Ложь);
КонецЕсли;
КонецЕсли;
ИмяФайлаРезультата = ПолучитьИмяВременногоФайла(Результат.Файл.ТекущаяВерсия.Расширение);
ИмяФайлаРезультата2 = ПолучитьИмяВременногоФайла(Результат.Файл.ТекущаяВерсия.Расширение);
ПутьКПрограммеКонвертацииPDF = РаботаСФайламиВызовСервера.ПолучитьПутьКПрограммеКонвертацииPDF();
стрПуть = " -density 150 -quality 100 " + ИмяФайлаСПутем + "[0] null: ";
Если ТипЗнч(Результат.Файл.ВладелецФайла) = Тип("СправочникСсылка.ВнутренниеДокументы")
ИЛИ ТипЗнч(Результат.Файл.ВладелецФайла) = Тип("СправочникСсылка.ВходящиеДокументы")
ИЛИ ТипЗнч(Результат.Файл.ВладелецФайла) = Тип("СправочникСсылка.ИсходящиеДокументы") Тогда
Штрихкод = ШтрихкодированиеСервер.СформироватьШтрихКод();
Штрихкод_ориг = ШтрихкодированиеСервер.ПолучитьШтрихКод(Документ.Ссылка);
если Штрихкод_ориг <> Неопределено тогда
Штрихкод = Штрихкод_ориг;
иначе
ШтрихкодированиеСервер.ПрисвоитьШтрихКод(Документ.Ссылка, Штрихкод);
конецесли;
НастройкиШтрихкода = ШтрихкодированиеСервер.ПолучитьПерсональныеНастройкиПоложенияШтрихкодаНаСтранице();
Если НЕ Штрихкод = Неопределено Тогда
ИмяВременногоФайлаКартинки = ПолучитьИмяВременногоФайла("JPG");
ДвоичныеДанныеИзображения = ШтрихкодированиеСервер.ПолучитьКартинкуШтрихкода(Штрихкод,, НастройкиШтрихкода.ВысотаШК, НастройкиШтрихкода.ПоказыватьЦифры).ПолучитьДвоичныеДанные();
ДвоичныеДанныеИзображения.Записать(ИмяВременногоФайлаКартинки);
Если ДвоичныеДанныеИзображения <> Неопределено Тогда
стрПуть = стрПуть + "( " + ИмяВременногоФайлаКартинки + " -resize +150% -quality 100 ) -gravity SouthEast -compose multiply -geometry +300+50 -layers composite ";
конецесли;
конецесли;
конецесли;
стрПуть = """" + ПутьКПрограммеКонвертацииPDF + """ " + стрПуть + " -font Tahoma -pointsize 12 -draw ""gravity SouthEast text 90,70 '"+ Строка(Документ.РегистрационныйНомер) + "'"" -draw ""gravity SouthEast text 90,40 '"+Строка(Формат(Документ.ДатаРегистрации, "ДЛФ=Д"))+ "'""" + " " + ИмяФайлаРезультата;
ЗапуститьПриложение(стрПуть,,Истина);
стрПуть = " -density 150 -quality 100 " + ИмяФайлаРезультата + " " + ИмяФайлаСПутем + "[1-10000] " + ИмяФайлаРезультата2;
стрПуть = """" + ПутьКПрограммеКонвертацииPDF + """ " + стрПуть;
ЗапуститьПриложение(стрПуть,,Истина);
ДвоичныеДанныеРезультата = Новый ДвоичныеДанные(ИмяФайлаРезультата2);
АвтозаполнениеШаблоновФайловСервер.ОбновитьВерсиюИзДвоичныхДанных(ДвоичныеДанныеРезультата, Результат.Файл, "Вставка штрихкода");
стрРезультат = Истина;
УдалитьФайлы(ИмяФайлаСПутем);
УдалитьФайлы(ИмяФайлаРезультата);
УдалитьФайлы(ИмяФайлаРезультата2);
УдалитьФайлы(ИмяВременногоФайлаКартинки);
Файл = Неопределено;
конеццикла;
Документ = Неопределено;
Возврат стрРезультат;
КонецФункции