Aether
|
|
« : 25-10-2013 08:01 » |
|
Добрый день. Для понимания проблемы, я упрощу ситуацию, но с сохранением смысла. Итак, требовалось решить задачу: произвести разметку листа бумаги в клетку заданного габарита с толщиной линии равной минимально возможной у данной модели принтера. Я нашёл решение следующего вида: сначала создал картинку bmp 1000Х1000 пикселей в ЧБ виде и начертил на ней 2 горизонтальные и 2 вертикальные линии так, чтобы между ними был промежуток в один пиксель. Далее, я вывел на печать принтером картинку несколько раз, изменяя разрешение в ней (dpi). Таким образом, я установил, какую толщину имеет пиксель в принтере в двух осях (разрешение собственно). Далее, я написал программу генерации bmp картинки размером с область печати заданного разрешения. И разметил её в клетку линиями толщиной в один пиксель с нужным шагом. При печати bmp файла, как средствами Windows и MS Office и Corel Photopaint и другими, наблюдался эффект пропадания линий на бумаге. То есть принтер не пропечатывает некоторые линии. Играя масштабом в программе печати, нужное было достигнуто и решено. НО, меня интересует: занимался ли кто-нибудь программированием принтера напрямую, и есть ли решение более правильное и точное. Буду рад даже ссылкам на мануалы, потому как тема точной передачи изображения на бумагу всплывает уже не один раз.
|
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #1 : 25-10-2013 09:36 » |
|
с толщиной линии равной минимально возможной у данной модели принтера. А вот с этого места поподробней. Эта фраза говорит, что ты не совсем понимаешь, как печатает принтер И... тип принтера? Струйник, лазерник, матричный, светодиодный, термобумага и т.д. Программировать принтер - это"грубо" подготовить поток вывода на языке принтера Который из себя представляет, опять же - грубо, две основных команды PenUp и PenDown Кроме того, продвинутые принтеры понимают некие сущности, такие как прямоугольник, окружность, линия, и рендеринг таких сущностей может происходить в самом принтере Качество печати, также зависит от качества носителя печати (родной порошок/чернила - заменители) Как-то упрощенная ситуация, без смысла. Играя масштабом в программе печати, нужное было достигнуто и решено
А паинт, корел - это не программы печати?
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Aether
|
|
« Ответ #2 : 25-10-2013 10:31 » |
|
Свои первые эксперименты я проделывал на лазерном HP laserjet 1018. Я опишу немного свои познания, возможно, они нуждаются в выправлении. Итак, принтер - физическое устройство, если он матричный, то минимальный пиксель, который он выдаёт - удар иглы определённого для данного устройства размера, если принтер струйный, то минимальный размер отпечатка диктуется размером дюзы, если лазерный, то размер пятна лазера на фотобарабане, производящий рассеяние заряда и соответственно вызывающий отлипание порошка. В любом варианте, какой бы принтер не был у него есть какой-то буфер типа bitmap. В лазерном случае это будет массив из битов отвечающий за то быть пикселю или нет. И тут собственно я и вижу проблему - обратится к этому буферу напрямую нельзя, можно "подготовить поток вывода на языек принтера" (типа post script). А затем внутренний "постпроцессор" принтера сделает всё необходимое и... результат. Проблема в том, что исходное изображение претерпевает ряд преобразований, мне не нужных, в ходе которых: сначала программа печати его модифицирует переводя на "язык принтера", потом полученное изменяет "постпроцессор" принтера - в итоге пропадение части информации. Применительно к линиям разметки, полагаю, имеют место быть ошибки округления в режиме ЧБ графики (не путать с ЧБ оттенками серого, только 1бит на пиксель).
О качестве печати я не говорю, например, если бы порошок был фуфловый, то линия была бы не пропечатана чётко, скорее всего с пробелами и мусором. Проблемы с фотобарабаном, тоже дают эффекты забелов, НО линия не пропечатана на всю длину, то есть это потеря данных в результате преобразований.
Упрощённая, на то и упрощённая). Просто хочу разобраться раз и на всегда, желательно, как выдать изображение без искажений: чтобы 1пиксель в массиве изображения соответствовал 1пикселю на бумаге.
|
|
|
Записан
|
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #3 : 25-10-2013 11:23 » |
|
Aether, как вариант - попробуйте сами сформировать команды принтеру на языке PostScript, если принтер его поддерживает.
|
|
|
Записан
|
|
|
|
Aether
|
|
« Ответ #4 : 25-10-2013 12:37 » |
|
Я и веду дело к этому)). Пока, я этой проблемой углублённо не занимался, но желание есть, а опыта и знаний нету. Вот и спрашиваю здесь, возможно, люди более опытные располагают и тем и другим. И готовы направить в нужном направлении. Вы в своём ответе уже задали ещё один вопрос: "если принтер его поддерживает". Сейчас читаю сервисный мануал: устройство преобразующее входящую информацию (print data) в массив точек в принтере (dot image), именуется Formatter system, а вот упоминания о том, что есть print data и на каком она языке - ни слова, в руководстве пользователя информации тоже не много, да и не факт, что эти данные будут точны, ибо в мануалах описывается, что комплектация конкретного аппарата может изменяться производителем без ведома. Отсюда вытекает: как средствами Windows определить на каком языке умеет общаться конкретный подключённый принтер, затем, выяснить, в случае списка, какой из них является "родным" для аппарата (во избежание лишних процессов преобразования в самом аппарате). Короче, пока витаю я в этом хозяйстве...
Теперь с другой стороны, существует ли годный для освоения мануал по PostScript. Может кто посоветует/поделится).
|
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #5 : 25-10-2013 12:45 » |
|
документация ищется в 2-3 клика
Дело в другом.
Рендерингом в любом случае будет выступать сам принтер. И именно принтер отвечает за минимальную точку. Если принтер посчитает ее не выводить, то он ее не выведет, или выведет так как ты этого не хотел.
Вот Джон доберется до темы, он, кажется, плотно с принтерами работал.
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Aether
|
|
« Ответ #6 : 25-10-2013 16:26 » |
|
Покопался по 2-3 клика, и вот что понял: если мы печатаем из MS Word, например, то он переводит страницу в формат PostScript, и передаёт драйверу принтера, далее драйвер определяет является ли этот язык (PS) родным для принтера, если да, то на печать, если нет, то он её переводит на родной это может быть PCL, ESC/P, HPGL, XES/UDK, LNO2+ и так далее, коих тьма, потом отправляет на печать. Есть какая-то смутная тема про GDI принтеры, в которых печать рендерит ЦП. Короче, пока всё смутно.
Буду ждать Джон`а)).
Добавлено через 1 день, 3 часа, 45 минут и 45 секунд: Сейчас, как небольшой ликбез читаю книжку "Программирование под MS-DOS". В ней есть статья про программирование матричного принтера. Судя по ней, всё управление обслуживается прерываниями int 17h, 21h, 2Fh.. Но не суть. Главное, что принтер можно инициализировать на печать в разных режимах, один из которых 1 в 1 как мне надо. Конечно, информация устаревшая.. главное, что останавливает попробовать - там всё упёрто на LPT порт, который этими программными прерываниями и обслуживается. Про USB в MSDOS как-то бредово.
|
|
« Последнее редактирование: 26-10-2013 20:12 от Aether »
|
Записан
|
|
|
|
Sla
|
|
« Ответ #7 : 26-10-2013 20:51 » |
|
Aether, и это правильно... это основы. Нужно просто отвлечься от окружения и понять смысл А смысл в простом
Управление принтером через интерфейс.
В той части где у тебя управление матр. принтером по lpt порту - это управляющие последовательности - превод принтера в граф режим, а далее управление самой печатью, т. по сути penUp/penDown
кстати... GDI принтер - и есть аналог. т.е. управление "головкой" напрямую из интерфейса.
Продвинутые принтеры (со своими мозгами) понимают язык графики тот же postscript или же в зависимости от модели свой собственный, то ли PCL, то ли ... ты об этих внутренних языках сам писал,
Чтоб ты понимал. Принтер - это самостоятельная единица, и он самостоятельно принимает решение о печати (рендеринг).
GDI - принтер, да, ты как управляющий процессом руководишь печатью. Но... сейчас стоимость процессора и препроцессора печати, по сравнению с предыдущими годами, до такой величины мала, что gdi принтера уже, кажется мне, и не выпускаются, этим вопросом давно не интересовался.
И все это к чему? Не понятно твое желание - понять и забыть.
Есть принтера с высокой разрешимостью, принтера для предпечатной подготовки. И, поверь, никто не работает на его максимальных возможностях. Есть принтера для фотопечати - и там... размер пятна (лазерного, чернильного) зависит исключительно от мозгов принтера.
И это все к чему?
Думаю, что ты поставил себе задачу изначально тупиковую. Такая задача доступна только разработчикам софта рендеринга принтера, и является, неким образом, технологической тайной.
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #8 : 26-10-2013 21:07 » |
|
Вот Джон и добрался. Сорри, но вчера работы было много... Итак. Вот это Таким образом, я установил, какую толщину имеет пиксель в принтере в двух осях (разрешение собственно). и прочие танцы с бубном выбрасываем. ПостСкрипт и Ворд и иже с ними забываем как кошмарный сон. Текущее разрешение принтера (если нужно) элементарно спрашивается у DC принтера: int nLogPixX = pDC->GetDeviceCaps(LOGPIXELSX); int nLogPixY = pDC->GetDeviceCaps(LOGPIXELSY); И не у каждого принтера можно заполнить ВСЮ поверхность бумаги. В силу конструкционных особенностей (типа ну хоть на чём-то бумага должна держаться) есть отступ, который принтером в силу этих особенностей не печатается. его тоже надо учитывать. К примеру: отступ принтера составляет 3 мм; первая линия должна проходить на расстоянии 5 мм от края, значит координата первой линии должна быть 5-3=2 мм. Эти параметры (отступы) тоже спрашиваются у DC принтера: int cx = pDC->GetDeviceCaps(PHYSICALOFFSETX); int cy = pDC->GetDeviceCaps(PHYSICALOFFSETY); как выдать изображение без искажений: чтобы 1пиксель в массиве изображения соответствовал 1пикселю на бумаге. Ответ очевиден - необходимо подготовить изображение с разрешением равным разрешению принтера, которое получаем у DC этого самого принтера (см. выше). Но и это всё слишком сложно. Если сформулировать задачу наоборот, то решение будет ещё более лёгким. Итак, если вот в такой форме подойдёт: как нарисовать линию, чтобы она ВЕЗДЕ имела минимальную толщину (другими словами - единичную толщину для соответствующего разрешения устройства вывода, будь то экран или принтер), то решение зависит исключительно от используемой библиотеки. Для GDI в ф-ю CreatePen надо передать нулевую толщину. If nWidth is zero, the pen is a single pixel wide, regardless of the current transformation. Если же используется gdi+, то тогда используем недокументированную фичу конструктора объекта Pen. Трюк заключается в отрицательном значении величины толщины. Например -1.0 решает все проблемы. Что я, собственно, и советую сделать. зы Конечно, в этом случае, в силу технологических особенностей могут проявляться эффекты типа: О качестве печати я не говорю, например, если бы порошок был фуфловый, то линия была бы не пропечатана чётко, скорее всего с пробелами и мусором. Проблемы с фотобарабаном, тоже дают эффекты забелов, но физически цель будет максимально достигнута - принтер будет СТАРАТЬСЯ напечатать линю толщиной в один пиксель.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Sla
|
|
« Ответ #9 : 26-10-2013 21:10 » |
|
Джон, я знал!!! На кое-что ты мне открыл глаза. Но мне это абсолютно не нужно, а просто отложится в копилку. тут есть нюанс - ведь состояние принтера мы опрашиваем через драйвер!!! но физически цель будет максимально достигнута - принтер будет СТАРАТЬСЯ напечатать линю толщиной в один пиксель. Вот!!! принтер будет стараться!
|
|
« Последнее редактирование: 26-10-2013 21:13 от Sla »
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #10 : 26-10-2013 22:34 » |
|
Совершенно верно, другого способа общения с принтером окромя драйвера нет (в нормальном случае, вариант напрямую работать с принтером через интерфейс (COM, LPT, USB etc.) здесь не рассматривается). Собственно DC и предоставляется драйвером GDI-принтера. Дальше по теории.
Ну и, собственно, любое устройство вывода будет "стараться". Ведь если на мониторе имеется дефектный пиксель, то линия через него прходящая тоже будет в этой точке "прерываться". Но это уже "физические" недостатки УВ, которые "лечатся" использованием устройств с необходимым качеством. Программно исправить такие недостатки невозможно. Более того, не стоит даже пытаться это сделать, ибо тогда программа будет "заточена" исключительно под это устройство.
|
|
« Последнее редактирование: 26-10-2013 22:41 от Джон »
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Aether
|
|
« Ответ #11 : 27-10-2013 13:30 » |
|
Ну почему сразу понять и забыть? Конечно это не такая частая проблема, куда более других). Тем не менее, встречается, иногда просто нужно отпечатать качественно (на пределе): например, схему печатной платы. Сейчас, требует внимания другая задача: настраиваю станки на изготовление малоразмерных деталей: кулачки, шестерни - средний размер 10-20мм. Вот вопрос, как снять размеры, например, с эвольвенты? Выяснить правильно ли работает инструмент?... Раньше в совке это решалось так: сидел отдел экспериментального макетирования размером с маленький отдельный завод. В нём изготовляли увеличенные шаблоны врукопашную, затем методом светокопии на их базе делали слайды, которые помещали в проектор; в него же клали и деталь. Далее по совмещению профилей определяли дефект и принимали меры. Я приспособился эти шаблоны печатать, так как разумной альтернативы нет, и точность принтера довольно высока - 720dpi - 1точка=35мкм, значит печатая с увеличением в х10 я получу объект с точностью в 3.5мкм, что достаточно, и как показывает практика явно лучше, чем модели ручного творчества. Вот пример практического применения, конечно, имеются специализированные аппараты типа цоллера для всех этих дел, но я не располагаю бюджетом для их покупки, и исхожу из того, что имею доступного под рукой.
Задача такова, что не всё в линии упирается). Это просто привёл, чтобы окружающие узрели корень. Я программно сформирую любой массив точек с учётом нужной математики.
Драйвер использовать разумно. Сейчас читаю GDI print API. По идее это универсальная библиотека для работы с любым принтером, а не только GDI-типом, и она не опирается на PS, PCL. Я правильно понимаю?
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #12 : 27-10-2013 13:49 » |
|
Сейчас, требует внимания другая задача: настраиваю станки на изготовление малоразмерных деталей: кулачки, шестерни - средний размер 10-20мм. Вот вопрос, как снять размеры, например, с эвольвенты? Выяснить правильно ли работает инструмент?... Раньше в совке это решалось так: сидел отдел экспериментального макетирования размером с маленький отдельный завод. В нём изготовляли увеличенные шаблоны врукопашную, затем методом светокопии на их базе делали слайды, которые помещали в проектор; в него же клали и деталь. Далее по совмещению профилей определяли дефект и принимали меры. Я приспособился эти шаблоны печатать, так как разумной альтернативы нет, и точность принтера довольно высока - 720dpi - 1точка=35мкм, значит печатая с увеличением в х10 я получу объект с точностью в 3.5мкм, что достаточно, и как показывает практика явно лучше, чем модели ручного творчества. А стоит ли изобретать велосипед? Сейчас с этой задачей справляются мало-мальски продвинутые кады.
|
|
|
Записан
|
|
|
|
Aether
|
|
« Ответ #13 : 27-10-2013 14:04 » |
|
В смысле, отрисовать эвольвентное колесо в CAD системе??? Во-первых, CAD заточен под конструктора, и в большинстве случает рисует не по мат. модели, а упрощённо. На глаз разница может быть и не очевидна, но для механизма это катастрофично. Во-вторых, проблема печати никуда не девается, а скорее ещё более усугубляется, так как CAD оперирует кривыми, а не точками, а кривые имеют толщину, что ещё добавляет жару. В-третьих, есть тьма технологических нюансов. Я хорошо владею CADами и CAMами, и если бы видел здесь упрощёнку, то естественно всё упростил, но не выходит.
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #14 : 27-10-2013 14:51 » |
|
Драйвер использовать разумно. Сейчас читаю GDI print API. По идее это универсальная библиотека для работы с любым принтером, а не только GDI-типом, и она не опирается на PS, PCL. Я правильно понимаю?
Исходя из выше сказанного (про 35 мкм) я посоветую тебе использовать gdi+. Подобная инициаллизация Graphics-объекта работает уже непосредственно с микрометрами: Status st; auto pgrMem = Graphics::FromHDC(pDC->GetSafeHdc()); st = pgrMem->SetSmoothingMode(SmoothingModeNone); // Avoid anti alias st = pgrMem->SetPageUnit(UnitMillimeter); st = pgrMem->SetPageScale((REAL)0.001); st = pgrMem->SetPixelOffsetMode(PixelOffsetModeHalf);
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
zubr
Гость
|
|
« Ответ #15 : 27-10-2013 16:02 » |
|
В смысле, отрисовать эвольвентное колесо в CAD системе??? Во-первых, CAD заточен под конструктора, и в большинстве случает рисует не по мат. модели, а упрощённо. На глаз разница может быть и не очевидна, но для механизма это катастрофично. Во-вторых, проблема печати никуда не девается, а скорее ещё более усугубляется, так как CAD оперирует кривыми, а не точками, а кривые имеют толщину, что ещё добавляет жару. В-третьих, есть тьма технологических нюансов. Я хорошо владею CADами и CAMами, и если бы видел здесь упрощёнку, то естественно всё упростил, но не выходит.
К примеру, берешь 3d-модель твоей шестерни и прокатываешь ее в мастеркам в обработке зуборезной фрезой, там и увидишь, правильная ли у тебя эвольвента.
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #16 : 27-10-2013 22:36 » |
|
Как не нарисуй, а фактическая форма зуба будет зависеть от станка и фрезы. Более точная форма будет получена естественным износом в процессе притирки пар. Следования идеальной форме эвольвенты смысла нет, т.к. (не думаю, что открываю глаза, но напоминаю) пятно контакта больше зависит от свойств материала колес, чем от точности изготовления.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
zubr
Гость
|
|
« Ответ #17 : 28-10-2013 02:19 » |
|
Обычно с шестернями вообще не заморачиваются, если только какой то высокоточный механизм. Есть стандартные модули, есть коэффициенты кореляции при смещении, есть готовые эмпиричекие формулы расчета, есть стандартный зуборезный инструмент - при правильном расчете нужная форма зуба получается в процессе механической обработки.
|
|
|
Записан
|
|
|
|
Aether
|
|
« Ответ #18 : 29-10-2013 13:32 » |
|
Джон, танцев с бубнами избежать не получается))) Но это уже привычное дело при любой наладке.
Итак, пока разбираюсь просто с GDI. Набросал программку формирующую шахматную доску и вывод её на печать. Аппарат завёлся, но результат был таков: просто чёрный квадрат. Ну, естественно, помимо принтера я её сбросил в bmp файл и проверил, что она присутствует там в норме. Решил, поступить иначе: установил виртуальный принтер Bullzip PDF, и вывел на него. Результат удачен: но шахматная доска получилась не в градациях чёрный/белый, как в bmp24bit (000000h-чёрный, FFFFFFh-белый), а в оттенках серого (вместо чёрного более серый, вместо белого слабосерый). Мне как-то смешно стало: получается задаёшь принтеру контрастное изображение, драйвер его сглаживает, а физический принтер, в силу своей чёрно-белости, всё что отлично от белого до какого-то порога округляет в чёрный и выдаёт так = чёрный квадрат Малевича)). Пока разбираюсь дальше... вроде успешно. Сейчас, целенаправлен на SetSmoothingMode(SmoothingModeNone); ибо как-то бороться с антиальясингом надо.
Спасибо.
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #19 : 30-10-2013 06:55 » |
|
А почему ты не хочешь попробовать с gdi+? Её специально сделали как ООП обёртку для GDI (ибо нет другого Бога под Виндой, кроме DirectX), чтобы облегчить жизнь, в частности, с настройками DC.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
|