Демотивационный постер/Генераторы
В эту статью нужно добавить как можно больше генераторов на LISP'е и PASCAL'е.
Также сюда можно добавить интересные факты, картинки и прочие кошерные вещи.
Тут свалены в кучу исходники софтеца, форматирующего жесткий диск генерирующего мотивационные постеры.
Генератор на sh с использованием SVG
#!/bin/sh TEMPLATE='<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="800" height="640" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <rect width="800" height="640" style="fill:rgb(0,0,0);"/> <rect x="75" y="50" width="650" height="440" style="stroke:rgb(255,255,255);stroke-width:1;"/> <image x="77" y="52" width="646px" height="436px" xlink:href="%s"/> <text text-anchor="middle" x="50%%" y="545" font-family="Times New Roman" font-size="55" style="fill:rgb(255,255,255);"> %s </text> <text text-anchor="middle" x="50%%" y="580" font-family="Verdana" font-size="20" style="fill:rgb(255,255,255);"> %s </text> </svg>'; printf "$TEMPLATE" "$1" "$2" "$3" | convert -quality 85 - "$4"
Употребление: ./generator.sh <картинка> <заголовок> <текст> <итоговая картинка.jpg>
Генератор на sh с использованием SVG 2
Внимание: используется программа convert из imagemagick.
#!/bin/sh# Demotivation by William Meth# ver. 0.4 Copyleft (C) 2009 BSD license## Отправляйте Ваши замечания и предложения на veyko2002'at'gmail.com## Thanks to:# ramok by http://linsovet.com# code cleaning## TODO: Сделать так чтобы опции решали необязательные параметры, а синтаксис# сводился к виду demotivation [-HoFfSsC ] "входящее изображение" "текст# заголовка" "текст пояснения" # Коды ошибокERROPT="1" # Неверная опцияENOVALUE="2" # Не прописано значение опцииENOIMAGE="3" # Не дан входной файлESCALE_ERR="4" # Не получилось изменить изображениеENODEPS="5" # Нерешенные зависимостиESHIT="265" # Маловероятная ошибка#несколько технических переменныхMYNAME=`basename $0` #получаем имя скриптаRC=$HOME/.${MYNAME}rc #Место нахождения конфига. #Создаем файл конфигурации, если еще не существует.#Пожалуйста, не изменяйте свои параметры тут! Для этого есть конфиг.if [ ! -f "$RC" ]; then cat << END_OF_RC > $RCDEST="dem\$(date +%N).png" # Имя файлаH_FONT="/usr/share/fonts/TTF/dejavu/DejaVuSans.ttf" # Шрифт заголовкаT_FONT="/usr/share/fonts/TTF/dejavu/DejaVuSans.ttf" # Шрифт поясненияH_SIZE="64" # Размер заголовкаT_SIZE="32" # Размер поясненияSCALE="640" # Размер END_OF_RCfi # считываем конфиг файл. $RC #Проверка наличия необходимых компонентовwhich convert &> /dev/nullif [ $? -gt 0 ]; then echo 'Для корректной работы программы требуется пакет "ImageMagic"' 1>&2 exit $ENODEPSfi motivator_help() {cat << END_OF_HELP$MYNAME - Генератор демотиваторовИспользование: $MYNAME -i КАРТИНКА [-o КАРТИНКА] [-h ТЕКСТ] [-t текст] [-f ШРИФТ] [-F ШРИФТ] [-s РАЗМЕР] [-S РАЗМЕР] [-C ЧИСЛО]Опции: -H - Показать эту справку -i - Исходное изображение -h - Текст заголовка -t - Текст пояснения -o - Выходной файл -F - Шрифт заголовка -f - Шрифт пояснения -S - Размер заголовка -s - Размер пояснения -C - Размер изображенияДля изменения параметров по умолчанию, редактируйте файл $RCEND_OF_HELP} motivator_getopts() { while getopts ":i: h: t: o: f: F: s: S: C: H" optname; do #получаем аргументы case "$optname" in "i") IMAGE="${OPTARG}" ;; "h") HEAD_TEXT="${OPTARG}" ;; "t") TERM_TEXT="${OPTARG}" ;; "o") DEST="${OPTARG}" ;; "f") T_FONT="${OPTARG}" ;; "F") H_FONT="${OPTARG}" ;; "s") T_SIZE="${OPTARG}" ;; "S") H_SIZE="${OPTARG}" ;; "C") SCALE="${OPTARG}" ;; "H") motivator_help; exit 0 ;; "?") echo "нет опции \"${OPTARG}\"! Используйте -H для справки" 1>&2; exit $ERROPT ;; ":") echo "Не указан аргумент для опции \"${OPTARG}\"" 1>&2; exit $ENOVALUE ;; *) echo "Неизвестная ошибка" 1>&2; exit $ESHIT ;; esacdone #Проверяем наличие входного файлаif [ -z "${IMAGE}" ]; then echo -e 'дайте мне исходную картинку!\n' 1>&2 motivator_help exit $ENOIMAGE fi} #------Основной код------ #получаем аргументыmotivator_getopts "${@}" #Изменяем размерconvert -scale "${SCALE}" "${IMAGE}" "${DEST}" &> /dev/nullif [ $? -gt 0 ]; then echo 'Ошибка изменения размера изображения' 1>&2 exit $ESCALE_ERRfi #Делаем рамкуmogrify -bordercolor black -border 2 \ -bordercolor white -border 2 \ -bordercolor black -border 70x0 "${DEST}" #Пишем заголовокif [ -n "${HEAD_TEXT}" ]; thenmontage -geometry +0+0 -background black -fill white \ -font "${H_FONT}" \ -pointsize "${H_SIZE}" -label "${HEAD_TEXT}" "${DEST}" "${DEST}"fi #Пишем пояснениеif [ -n "${TERM_TEXT}" ]; thenmontage -geometry +0+0 -background black -fill white \ -font "${T_FONT}" \ -pointsize "${T_SIZE}" -label "${TERM_TEXT}" "${DEST}" "${DEST}"fi #Если был заголовок или пояснение, делаем поляif [ -n "${HEAD_TEXT}" -o -n "${TERM_TEXT}" ]; then mogrify -bordercolor black -border 5x45 "${DEST}"fi exit 0 #все хорошо, закончили. Уходим отсюда!
Генератор на C++
#include <string>#include <iostream>#include <Magick++.h>// для получения Magick++ нужно идти на http://www.graphicsmagick.org/// скачать бесплатно и без смсusing namespace std;using namespace Magick;int main(int argc, char *argv[]){ if (argc >= 5) // аргументов должно быть больше или равно пяти { // открывающая фигурная скобка string title = argv[1]; string text = argv[2]; string in_file = argv[3]; string out_file = argv[4]; try { Image in_image; in_image.read(in_file); int border_margin = 50, border_padding = 5, image_width = in_image.size().width() + border_margin * 2 + border_padding * 2, image_height = in_image.size().height() + border_margin * 4 + border_padding * 2, border_top = border_margin, border_left = border_margin, border_right = image_width - border_margin, border_bottom = image_height - border_margin * 3, border_thickness = 2, title_size = 48, text_size = 24; Image out_image(Geometry(image_width, image_height), Color("black")); // *** Рисуем картинку в рамке *** out_image.strokeColor("white"); out_image.fillColor("black"); out_image.strokeWidth(border_thickness); out_image.draw(DrawableRectangle(border_left, border_top, border_right, border_bottom)); // *** Рисуем текст *** out_image.draw(DrawableTextAntialias(true)); out_image.draw(DrawableStrokeAntialias(true)); out_image.draw(DrawableCompositeImage(border_left + border_padding, border_top + border_padding, 0, 0, in_image)); out_image.fillColor("white"); out_image.strokeWidth(0); out_image.strokeAntiAlias(true); out_image.antiAlias(true); out_image.font("@times.ttf"); // позаботиться о том, чтобы программа нашла шрифты out_image.fontPointsize(title_size); out_image.annotate(title, Geometry(0, 0, 0, border_bottom), NorthGravity, 0); out_image.font("@arial.ttf"); // позаботиться о том, чтобы программа нашла шрифты out_image.fontPointsize(text_size); out_image.annotate(text, Geometry(0, 0, 0, border_bottom + title_size + 25), NorthGravity); out_image.write(out_file); } catch (exception &exc) { cout << "Caught exception: " << exc.what() << endl; return 1; } } else { cout << argv[0] << " <title> <text> <input file> <output file>" << endl; return 1; } return 0;}
Генератор на жабке
//Мудачьё, вы где класс MotGenerator потеряли?
/* == MotMaker == *//* version 1.1.0 *//* (c) 2008 Anonymous. *//* Distributed under the terms of GNU GPL v2. */package motmaker;import java.awt.*;public class MotPreviewCanvas extends Canvas implements Runnable { protected MotGenerator motGenerator; protected Image scaledMotImage; protected int scaledXPos; protected int scaledYPos; private final Thread motPreviewThread; private boolean threadRunning; private boolean needsUpdate; private long lastTimeMillis; protected static final String PLASE_WAIT_STR = "Please wait..."; protected MotPreviewCanvas() { this(null); } public MotPreviewCanvas(MotGenerator generator) { super(); this.motGenerator = generator; this.scaledMotImage = null; this.motPreviewThread = new Thread(this); this.threadRunning = false; this.needsUpdate = true; this.lastTimeMillis = System.currentTimeMillis(); this.scaledXPos = 0; this.scaledYPos = 0; } public void paint(Graphics g) { if (this.scaledMotImage != null) { /* draw scaled motivator */ g.drawImage(this.scaledMotImage, this.scaledXPos, this.scaledYPos, this); } else { int width = super.getWidth(); int height = super.getHeight(); g.setColor(Color.WHITE); g.setFont(new Font("SansSerif", Font.PLAIN, 10)); g.fillRect(0, 0, width, height); FontMetrics fm = g.getFontMetrics(); int strHeight = fm.getHeight(); int strWidth = fm.stringWidth(PLASE_WAIT_STR); g.setColor(Color.GRAY); g.drawString( PLASE_WAIT_STR, (width - strWidth) / 2 - 1, (height - strHeight) / 2 - 1 ); } } void resetScaledMotImage() { this.scaledMotImage = null; super.repaint(); } public void requestUpdate() { if (!this.threadRunning) { this.motPreviewThread.start(); this.threadRunning = true; } this.needsUpdate = true; } public void run() { while (true) { long millis = System.currentTimeMillis(); if ((millis - this.lastTimeMillis) > 500) { this.lastTimeMillis = millis; if (this.needsUpdate) { Image motivatorImg = (this.motGenerator == null) ? null : this.motGenerator.getMotivatorImage(); if (motivatorImg != null) { int canvasWidth = super.getWidth(); int canvasHeight = super.getHeight(); int motImgWidth = this.motGenerator.getMotivatorImageWidth(); int motImgHeight = this.motGenerator.getMotivatorImageHeight(); if (motImgWidth == 0) motImgWidth = canvasWidth; if (motImgHeight == 0) motImgHeight = canvasHeight; double wCoeff = (double)canvasWidth / (double)motImgWidth; double hCoeff = (double)canvasHeight / (double)motImgHeight; int scaledWidth = canvasWidth; int scaledHeight = canvasHeight; if (wCoeff < hCoeff) { /* scaledWidth = canvasWidth; */ scaledHeight = (int)(motImgHeight * wCoeff); } else if (hCoeff < wCoeff) { scaledWidth = (int)(motImgWidth * hCoeff); /* scaledHeight = canvasHeight; */ } this.scaledMotImage = motivatorImg.getScaledInstance( scaledWidth, scaledHeight, Image.SCALE_SMOOTH /* Image.SCALE_AREA_AVERAGING */ ); this.scaledXPos = (canvasWidth - scaledWidth) / 2; this.scaledYPos = (canvasHeight - scaledHeight) / 2; } else { this.scaledMotImage = null; } super.repaint(); this.needsUpdate = false; } } } } }
Генератор на дотнетах
using System;using System.Text;using System.IO;using System.Drawing;namespace MotivatorGenerator{ class Program { static string headerFontName = "Roman"; static float headerSize = 48.0f; static string textFontName = "Roman"; static float textSize = 24.0f; static int imageMargin = 50; static int borderMargin = 10; static int borderPenWidth = 2; static int borderWidth = 6; static int borderPadding = 11; static int Main(string[] args) { if (args.Length < 3) { var executableName = Path.GetFileName(typeof(Program).Assembly.Location); Console.WriteLine("usage: {0} imagePath \"header\" \"text\"", executableName); Console.WriteLine("\t\t\t imagePath - full path to (de-)motivator picture"); Console.WriteLine("\t\t\t header - motivator header"); Console.WriteLine("\t\t\t text - motivator text"); Console.WriteLine("press any key to terminate"); Console.Read(); return 1; // WRONG_ARGUMENTS } string imagePath = args[0]; string header = args[1]; string text = args[2]; if (!File.Exists(imagePath)) { Console.WriteLine("picture file not found"); return 2; // IMAGE_NOT_FOUND } var motivatorImage = Image.FromFile(imagePath); // create graphics object for text measures var graphics = Graphics.FromImage(motivatorImage); // text parameters, used for measures and for drawing // format var textFormat = new StringFormat(); textFormat.Alignment = StringAlignment.Center; textFormat.LineAlignment = StringAlignment.Near; // font var headerFont = new Font(headerFontName, headerSize); var textFont = new Font(textFontName, textSize); // border var borderPen = new Pen(Color.White, borderPenWidth); // measures var headerHeight = (int)graphics.MeasureString(header, headerFont, motivatorImage.Width, textFormat).Height; var textHeight = (int)graphics.MeasureString(text, textFont, motivatorImage.Width, textFormat).Height; var outputImageWidth = motivatorImage.Width + imageMargin * 2 + borderWidth * 2 + borderPadding * 2; var outputImageHeight = motivatorImage.Height + textHeight + headerHeight + imageMargin * 2 + borderPadding * 2 + borderMargin * 4; // Height var outputPixelFormat = System.Drawing.Imaging.PixelFormat.Format24bppRgb; // create output image var outputImage = new Bitmap(outputImageWidth, outputImageHeight, outputPixelFormat); // release graphics after measures graphics.Dispose(); // create canvas from output image graphics = Graphics.FromImage(outputImage); graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; // prepare shapes var imageRectangle = new Rectangle(imageMargin + borderPadding, imageMargin + borderPadding, motivatorImage.Width, motivatorImage.Height); var headerRectangle = new Rectangle(imageRectangle.Left, imageRectangle.Bottom + borderMargin, motivatorImage.Width, headerHeight); var textRectangle = new Rectangle(headerRectangle.Left, headerRectangle.Bottom + borderMargin, motivatorImage.Width, textHeight); var borderRectangle1 = new Rectangle(imageRectangle.Left - borderPadding, imageRectangle.Top - borderPadding, imageRectangle.Width + borderPadding * 2, imageRectangle.Height + borderPadding * 2); var borderRectangle2 = new Rectangle(imageRectangle.Left - borderPadding + 3, imageRectangle.Top - borderPadding + 3, imageRectangle.Width + borderPadding * 2 - 6, imageRectangle.Height + borderPadding * 2 - 6); // draw graphics.Clear(Color.Black); // border graphics.DrawRectangle(borderPen, borderRectangle1); graphics.DrawRectangle(borderPen, borderRectangle2); // image graphics.DrawImage(motivatorImage, imageRectangle); // header graphics.DrawString(header, headerFont, Brushes.White, headerRectangle, textFormat); // text graphics.DrawString(text, textFont, Brushes.White, textRectangle, textFormat); // clean up graphics.Dispose(); motivatorImage.Dispose(); // save output image in same directory, but with new name var outputImagePath = Path.Combine(Path.GetDirectoryName(imagePath), Path.GetFileNameWithoutExtension(imagePath)) + "_{0}.png"; outputImagePath = string.Format(outputImagePath, header); if (File.Exists(outputImagePath)) File.Delete(outputImagePath); outputImage.Save(outputImagePath, System.Drawing.Imaging.ImageFormat.Png); return 0; // OK } }}
Генератор на питонах
Путь к шрифтам и сгенерированной картинке возможно придется поменять под свою систему.
#!/usr/bin/env pythonfrom PIL import Image, ImageDraw, ImageFontfrom sys import argv, exitif len(argv) < 4: print "demotivator.py imagefile header description [bg_color]" print "\tExample: python demotivator.py image.png 'Demotivator' 'This is demotivator'" exit(0)TOP_BORDER=40BOTTOM_BORDER=20LEFT_BORDER=40RIGHT_BORDER=40BIG_FONT_SIZE=48SMALL_FONT_SIZE=16BG_COLOR="#010101"if len(argv) > 4: BG_COLOR=argv[4]# Loading fontsbig_font = ImageFont.truetype("/usr/share/fonts/TTF/LiberationSans-Regular.ttf", BIG_FONT_SIZE, encoding="unic")header = unicode(argv[2], 'utf8')big_font_size = big_font.getsize(header)small_font = ImageFont.truetype("/usr/share/fonts/TTF/LiberationSans-Regular.ttf", SMALL_FONT_SIZE, encoding="unic")descr = unicode(argv[3], 'utf8')small_font_size = small_font.getsize(descr)# Calculating size of demotivatorsrc_img = Image.open(argv[1])src_size = src_img.getbbox()[2:]dst_size = list(src_size)dst_size[0] += LEFT_BORDER + RIGHT_BORDERdst_size[1] += TOP_BORDER + BOTTOM_BORDER + \ big_font_size[1] + small_font_size[1] + 5# Making borderdst_img = Image.new("RGB", dst_size, "black")dst_draw = ImageDraw.Draw(dst_img)dst_draw.rectangle([0, 0, dst_size[0], dst_size[1]], fill=BG_COLOR)dst_img.paste(src_img, (LEFT_BORDER, TOP_BORDER))# Drawing border linesdst_draw.line( (LEFT_BORDER - 3, TOP_BORDER - 3, dst_size[0] - RIGHT_BORDER + 3, TOP_BORDER - 3), width=1)dst_draw.line( (dst_size[0] - RIGHT_BORDER + 3, TOP_BORDER - 3, dst_size[0] - RIGHT_BORDER + 3, TOP_BORDER + src_size[1] + 3), width=1)dst_draw.line( (LEFT_BORDER - 3, TOP_BORDER + src_size[1] + 3, dst_size[0] - RIGHT_BORDER + 3, TOP_BORDER + src_size[1] + 3), width=1)dst_draw.line( (LEFT_BORDER - 3, TOP_BORDER + src_size[1] + 3, LEFT_BORDER - 3, TOP_BORDER - 3), width=1)# Drawing texttext_pos_x = (dst_size[0] - big_font_size[0]) / 2text_pos_y = src_img.getbbox()[3] + TOP_BORDER + 5dst_draw.text((text_pos_x, text_pos_y), header, font=big_font)text_pos_x = (dst_size[0] - small_font_size[0]) / 2text_pos_y += big_font_size[1] + 5dst_draw.text((text_pos_x, text_pos_y), descr, font=small_font)# Saving and showing imagedst_img.save("/tmp/demotivator.png", "PNG")dst_img.show()
Генератор на ПыхПых под винду
<?php //////// http://s.lurkmore.ru/images/a/ac/James_carriage.jpg // example of usage: // php dmotigen.php "James_carriage.jpg" "БАССЕЙН ЗАКРЫТ" "в нём дети и СПИД" // constants $fontFolder = "C:/Windows/Fonts/"; $fontExt = ".ttf"; $headerFont = "georgia"; $headerSize = 32.5; $textFont = "arial"; $textSize = 24.0; $imageMargin = 20; $spacing = 16; $borderPad = 16; // php dmotigen.php pict head text if( $_SERVER["argc"] != 4 ){ echo "usage: dmotigen.php pict head text\n". "\t pict - motivator image\n". "\t head - motivator header\n". "\t text - motivator text\n"; exit; } $srcFile = $_SERVER["argv"][1]; $header = iconv("CP1251", "UTF-8", $_SERVER["argv"][2]); $text = iconv("CP1251", "UTF-8", $_SERVER["argv"][3]); if( !file_exists( $srcFile ) ){ echo "picture file not found\n"; exit; } $img = imagecreatefromjpeg( $srcFile ); list($w, $h) = getimagesize( $srcFile ); $ha1 = imagettfbbox($headerSize, 0, $fontFolder.$headerFont.$fontExt, $header ); $ha2 = imagettfbbox($textSize, 0, $fontFolder.$textFont.$fontExt, $text ); $wt1 = $ha1[2]-$ha1[0]; $ht1 = $ha1[1]-$ha1[7]; $wt2 = $ha2[2]-$ha2[0]; $ht2 = $ha2[1]-$ha2[7]; $fw = $w + 8 + $imageMargin * 2 + $borderPad * 2; $fh = $h + 8 + $imageMargin * 2 + $borderPad * 2 + $ht1 + $ht2 + $spacing * 3; $fon = imagecreatetruecolor($fw, $fh); $white = imagecolorallocate( $fon, 255, 255, 255 ); $black = imagecolorallocate( $fon, 0, 0, 0 ); imagefill( $fon, 0, 0, $black ); imagecopy( $fon, $img, $imageMargin + $borderPad + 4, $imageMargin + $borderPad + 4, 0, 0, $w, $h ); imagerectangle( $fon, $imageMargin + $borderPad + 4 - 3, $imageMargin + $borderPad + 4 - 3, $imageMargin + $borderPad + $w + 4 + 2, $imageMargin + $borderPad + $h + 4 + 2, $white ); imagerectangle( $fon, $imageMargin + $borderPad + 4 - 4, $imageMargin + $borderPad + 4 - 4, $imageMargin + $borderPad + $w + 4 + 3, $imageMargin + $borderPad + $h + 4 + 3, $white ); imagettftext( $fon, $headerSize, 0, ($fw - $wt1) / 2, $imageMargin + $borderPad*2 + 8 + $h + $ht1 + $spacing, $white, $fontFolder.$headerFont.$fontExt, $header ); imagettftext( $fon, $textSize, 0, ($fw - $wt2) / 2, $imageMargin + $borderPad*2 + 8 + $h + $ht1 + $ht2 + $spacing*2, $white, $fontFolder.$textFont.$fontExt, $text ); imagejpeg( $fon, "dmotigen.jpg", 98 ); imagecolordeallocate( $fon, $black ); imagecolordeallocate( $fon, $white ); imagedestroy( $fon );?>
Допиленный генератор на ПыхПых под винду
- Интерактивный консольный интерфейс
- Запоминает настройки последнего дема
- Версия генератора под GNU/Linux — см. ниже
В папке генератора надо создать папку fonts с шрифтами, либо исправить переменную на папку системных шрифтов, либо скачать готовый архив (соджержит шрифты DejaVu) у меня в блоге или по прямой ссылке.
by Raegdan
<?php // Генератор демотиваторов на PHP // Требует библиотеку gd2 (php_gd2.dll на Windows) // Поддерживается ТОЛЬКО jpeg // ==== НАСТРОЙКИ =========================================================================================== // $fontFolder = "fonts/"; // Папка с шрифтами $fontExt = ".ttf"; // Расширение шрифтов // ==== КОД ================================================================================================= // if (!file_exists("memory")) { $mem = fopen("memory", "w+"); fwrite($mem, '<?php $lastSrcFile="mainecoon.jpg";$lastHeader="ПУШИСТЕ КОТЭ";$lastHeaderFont="DejaVuSerif";$lastHeaderSize=32.5;$lastText="риальне пушисте";$lastTextFont="DejaVuSans";$lastTextSize="24";$lastImageMargin=20;$lastSpacing=16;$lastBorderPad=16;'); fclose($mem); } include("memory"); function c2i ($cp1251) { return iconv("CP1251", "IBM866", $cp1251); } function i2c ($oem866) { return iconv("IBM866", "CP1251", $oem866); } function c2u ($cp1251) { return iconv("CP1251", "UTF-8", $cp1251); } echo c2i ( "\r\nDemGen - генератор демотиваторов, версия 1.0\r\n" . "Сделал Raegdan [http://raegdan1406.livejournal.com/]\r\n" . "Лицензия: GNU GPL v3 [http://www.gnu.org/]\r\n\r\n" ); echo c2i ("Введите имя исходной картинки [$lastSrcFile]: "); $srcFile = i2c((fgets(fopen("php://stdin", "r")))); $srcFile = trim($srcFile); if ($srcFile == "") { $srcFile = $lastSrcFile; } if( !file_exists( $srcFile ) ){ echo c2i("Ошибка: файл не существует. Выход.\r\n"); exit; } echo c2i ("Введите текст заголовка демотиватора [$lastHeader]: "); $headerRaw = i2c(fgets(fopen("php://stdin", "r"))); $headerRaw = trim($headerRaw); if ($headerRaw == "") { $headerRaw = $lastHeader; } $header = c2u($headerRaw); echo c2i ("Укажите шрифт заголовка [$lastHeaderFont]: "); $headerFont = i2c(fgets(fopen("php://stdin", "r"))); $headerFont = trim($headerFont); if ($headerFont == "") { $headerFont = $lastHeaderFont; } if (!file_exists($fontFolder . $headerFont . $fontExt)) { echo c2i("Ошибка: шрифт не существует. Выход."); exit; } echo c2i("Укажите размер шрифта заголовка [$lastHeaderSize]: "); $headerSizeRaw = i2c(fgets(fopen("php://stdin", "r"))); $headerSizeRaw = trim($headerSizeRaw); $headerSize = (float) $headerSizeRaw; if ($headerSize == 0) { $headerSize = $lastHeaderSize; } echo c2i("Введите текст демотиватора [$lastText]: "); $textRaw = i2c(fgets(fopen("php://stdin", "r"))); $textRaw = trim($textRaw); if ($textRaw == "") { $textRaw = $lastText; } $text = c2u($textRaw); echo c2i("Укажите шрифт текста [$lastTextFont]: "); $textFont = i2c(fgets(fopen("php://stdin", "r"))); $textFont = trim($textFont); if ($textFont == "") { $textFont = $lastTextFont; } if (!file_exists($fontFolder . $textFont . $fontExt)) { echo c2i("Ошибка: шрифт не существует. Выход."); exit; } echo c2i("Укажите размер шрифта текста [$lastTextSize]: "); $textSizeRaw = i2c(fgets(fopen("php://stdin", "r"))); $textSizeRaw = trim($textSizeRaw); $textSize = (float) $textSizeRaw; if ($textSize == 0) { $textSize = $lastTextSize; } echo c2i("Укажите ширину внешней рамки [$lastImageMargin]: "); $imageMarginRaw = i2c(fgets(fopen("php://stdin", "r"))); $imageMarginRaw = trim($imageMarginRaw); $imageMargin = (int) $imageMarginRaw; if ($imageMargin == 0) { $imageMargin = $lastImageMargin; } echo c2i("Укажите расстояние между заголовком и текстом [$lastSpacing]: "); $spacingRaw = i2c(fgets(fopen("php://stdin", "r"))); $spacingRaw = trim($spacingRaw); $spacing = (int) $spacingRaw; if ($spacing == 0) { $spacing = $lastSpacing; } echo c2i("Укажите расстояние между картинкой и заголовком [$lastBorderPad]: "); $borderPadRaw = i2c(fgets(fopen("php://stdin", "r"))); $borderPadRaw = trim($borderPadRaw); $borderPad = (int) $borderPadRaw; if ($borderPad == 0) { $borderPad = $lastBorderPad; } $mem = fopen("memory", "w+"); fwrite($mem, '<?php $lastSrcFile="' . $srcFile . '";$lastHeader="' . $headerRaw . '";$lastHeaderFont="' . $headerFont . '";$lastHeaderSize=' . $headerSize . ';$lastText="' . $textRaw . '";$lastTextFont="' . $textFont . '";$lastTextSize="' . $textSize . '";$lastImageMargin=' . $imageMargin . ';$lastSpacing=' . $spacing . ';$lastBorderPad=' . $borderPad . ';'); fclose($mem); echo c2i("Укажите имя файла демотиватора [" . implode(".", explode(".", $srcFile, -1)) . "-dem.jpg]: "); $demFile = i2c(fgets(fopen("php://stdin", "r"))); $demFile = trim($demFile); if ($demFile == "") { $demFile = implode(".", explode(".", $srcFile, -1)) . "-dem.jpg"; } ///////////////////////////////////////////////////////////////////////////// $img = imagecreatefromjpeg( $srcFile ); list($w, $h) = getimagesize( $srcFile ); $ha1 = imagettfbbox($headerSize, 0, $fontFolder.$headerFont.$fontExt, $header ); $ha2 = imagettfbbox($textSize, 0, $fontFolder.$textFont.$fontExt, $text ); $wt1 = $ha1[2]-$ha1[0]; $ht1 = $ha1[1]-$ha1[7]; $wt2 = $ha2[2]-$ha2[0]; $ht2 = $ha2[1]-$ha2[7]; $fw = $w + 8 + $imageMargin * 2 + $borderPad * 2; $fh = $h + 8 + $imageMargin * 2 + $borderPad * 2 + $ht1 + $ht2 + $spacing * 3; $fon = imagecreatetruecolor($fw, $fh); $white = imagecolorallocate( $fon, 255, 255, 255 ); $black = imagecolorallocate( $fon, 0, 0, 0 ); imagefill( $fon, 0, 0, $black ); imagecopy( $fon, $img, $imageMargin + $borderPad + 4, $imageMargin + $borderPad + 4, 0, 0, $w, $h ); imagerectangle( $fon, $imageMargin + $borderPad + 4 - 3, $imageMargin + $borderPad + 4 - 3, $imageMargin + $borderPad + $w + 4 + 2, $imageMargin + $borderPad + $h + 4 + 2, $white ); imagerectangle( $fon, $imageMargin + $borderPad + 4 - 4, $imageMargin + $borderPad + 4 - 4, $imageMargin + $borderPad + $w + 4 + 3, $imageMargin + $borderPad + $h + 4 + 3, $white ); imagettftext( $fon, $headerSize, 0, ($fw - $wt1) / 2, $imageMargin + $borderPad*2 + 8 + $h + $ht1 + $spacing, $white, $fontFolder.$headerFont.$fontExt, $header ); imagettftext( $fon, $textSize, 0, ($fw - $wt2) / 2, $imageMargin + $borderPad*2 + 8 + $h + $ht1 + $ht2 + $spacing*2, $white, $fontFolder.$textFont.$fontExt, $text ); imagejpeg( $fon, $demFile, 98 ); echo c2i("\r\nСохранено: " . $demFile . "\r\n"); imagecolordeallocate( $fon, $black ); imagecolordeallocate( $fon, $white ); imagedestroy( $fon );?>
Пингвинья версия предыдущего генератора
- Интерактивный консольный интерфейс
- Запоминает настройки последнего дема
В папке генератора надо создать папку fonts с шрифтами, либо исправить переменную на папку системных шрифтов, либо скачать готовый архив (соджержит шрифты DejaVu) у меня в блоге или по прямой ссылке.
По сравнению с виндовой изменены кодировки, так как пингвин кодирует всё в UTF8
by Raegdan
<?php // Генератор демотиваторов на PHP // Требует библиотеку gd2 (php_gd2.dll на Windows) // Поддерживается ТОЛЬКО jpeg // ==== НАСТРОЙКИ =========================================================================================== // $fontFolder = "fonts/"; // Папка с шрифтами $fontExt = ".ttf"; // Расширение шрифтов // ==== КОД ================================================================================================= // if (!file_exists("memory")) { $mem = fopen("memory", "w+"); fwrite($mem, '<?php $lastSrcFile="mainecoon.jpg";$lastHeader="ПУШИСТЕ КОТЭ";$lastHeaderFont="DejaVuSerif";$lastHeaderSize=32.5;$lastText="риальне пушисте";$lastTextFont="DejaVuSans";$lastTextSize="24";$lastImageMargin=20;$lastSpacing=16;$lastBorderPad=16;'); fclose($mem); } include("memory"); echo ( "\r\nDemGen - генератор демотиваторов, версия 1.0\r\n" . "Сделал Raegdan [http://raegdan1406.livejournal.com/]\r\n" . "Лицензия: GNU GPL v3 [http://www.gnu.org/]\r\n\r\n" ); echo ("Введите имя исходной картинки [$lastSrcFile]: "); $srcFile = (fgets(fopen("php://stdin", "r"))); $srcFile = trim($srcFile); if ($srcFile == "") { $srcFile = $lastSrcFile; } if( !file_exists( $srcFile ) ){ echo ("Ошибка: файл не существует. Выход.\r\n"); exit; } echo ("Введите текст заголовка демотиватора [$lastHeader]: "); $headerRaw = fgets(fopen("php://stdin", "r")); $headerRaw = trim($headerRaw); if ($headerRaw == "") { $headerRaw = $lastHeader; } $header = $headerRaw; echo ("Укажите шрифт заголовка [$lastHeaderFont]: "); $headerFont = fgets(fopen("php://stdin", "r")); $headerFont = trim($headerFont); if ($headerFont == "") { $headerFont = $lastHeaderFont; } if (!file_exists($fontFolder . $headerFont . $fontExt)) { echo ("Ошибка: шрифт не существует. Выход."); exit; } echo ("Укажите размер шрифта заголовка [$lastHeaderSize]: "); $headerSizeRaw = fgets(fopen("php://stdin", "r")); $headerSizeRaw = trim($headerSizeRaw); $headerSize = (float) $headerSizeRaw; if ($headerSize == 0) { $headerSize = $lastHeaderSize; } echo ("Введите текст демотиватора [$lastText]: "); $textRaw = fgets(fopen("php://stdin", "r")); $textRaw = trim($textRaw); if ($textRaw == "") { $textRaw = $lastText; } $text = $textRaw; echo ("Укажите шрифт текста [$lastTextFont]: "); $textFont = fgets(fopen("php://stdin", "r")); $textFont = trim($textFont); if ($textFont == "") { $textFont = $lastTextFont; } if (!file_exists($fontFolder . $textFont . $fontExt)) { echo ("Ошибка: шрифт не существует. Выход."); exit; } echo ("Укажите размер шрифта текста [$lastTextSize]: "); $textSizeRaw = fgets(fopen("php://stdin", "r")); $textSizeRaw = trim($textSizeRaw); $textSize = (float) $textSizeRaw; if ($textSize == 0) { $textSize = $lastTextSize; } echo ("Укажите ширину внешней рамки [$lastImageMargin]: "); $imageMarginRaw = fgets(fopen("php://stdin", "r")); $imageMarginRaw = trim($imageMarginRaw); $imageMargin = (int) $imageMarginRaw; if ($imageMargin == 0) { $imageMargin = $lastImageMargin; } echo ("Укажите расстояние между заголовком и текстом [$lastSpacing]: "); $spacingRaw = fgets(fopen("php://stdin", "r")); $spacingRaw = trim($spacingRaw); $spacing = (int) $spacingRaw; if ($spacing == 0) { $spacing = $lastSpacing; } echo ("Укажите расстояние между картинкой и заголовком [$lastBorderPad]: "); $borderPadRaw = fgets(fopen("php://stdin", "r")); $borderPadRaw = trim($borderPadRaw); $borderPad = (int) $borderPadRaw; if ($borderPad == 0) { $borderPad = $lastBorderPad; } $mem = fopen("memory", "w+"); fwrite($mem, '<?php $lastSrcFile="' . $srcFile . '";$lastHeader="' . $headerRaw . '";$lastHeaderFont="' . $headerFont . '";$lastHeaderSize=' . $headerSize . ';$lastText="' . $textRaw . '";$lastTextFont="' . $textFont . '";$lastTextSize="' . $textSize . '";$lastImageMargin=' . $imageMargin . ';$lastSpacing=' . $spacing . ';$lastBorderPad=' . $borderPad . ';'); fclose($mem); echo ("Укажите имя файла демотиватора [" . implode(".", explode(".", $srcFile, -1)) . "-dem.jpg]: "); $demFile = fgets(fopen("php://stdin", "r")); $demFile = trim($demFile); if ($demFile == "") { $demFile = implode(".", explode(".", $srcFile, -1)) . "-dem.jpg"; } ///////////////////////////////////////////////////////////////////////////// $img = imagecreatefromjpeg( $srcFile ); list($w, $h) = getimagesize( $srcFile ); $ha1 = imagettfbbox($headerSize, 0, $fontFolder.$headerFont.$fontExt, $header ); $ha2 = imagettfbbox($textSize, 0, $fontFolder.$textFont.$fontExt, $text ); $wt1 = $ha1[2]-$ha1[0]; $ht1 = $ha1[1]-$ha1[7]; $wt2 = $ha2[2]-$ha2[0]; $ht2 = $ha2[1]-$ha2[7]; $fw = $w + 8 + $imageMargin * 2 + $borderPad * 2; $fh = $h + 8 + $imageMargin * 2 + $borderPad * 2 + $ht1 + $ht2 + $spacing * 3; $fon = imagecreatetruecolor($fw, $fh); $white = imagecolorallocate( $fon, 255, 255, 255 ); $black = imagecolorallocate( $fon, 0, 0, 0 ); imagefill( $fon, 0, 0, $black ); imagecopy( $fon, $img, $imageMargin + $borderPad + 4, $imageMargin + $borderPad + 4, 0, 0, $w, $h ); imagerectangle( $fon, $imageMargin + $borderPad + 4 - 3, $imageMargin + $borderPad + 4 - 3, $imageMargin + $borderPad + $w + 4 + 2, $imageMargin + $borderPad + $h + 4 + 2, $white ); imagerectangle( $fon, $imageMargin + $borderPad + 4 - 4, $imageMargin + $borderPad + 4 - 4, $imageMargin + $borderPad + $w + 4 + 3, $imageMargin + $borderPad + $h + 4 + 3, $white ); imagettftext( $fon, $headerSize, 0, ($fw - $wt1) / 2, $imageMargin + $borderPad*2 + 8 + $h + $ht1 + $spacing, $white, $fontFolder.$headerFont.$fontExt, $header ); imagettftext( $fon, $textSize, 0, ($fw - $wt2) / 2, $imageMargin + $borderPad*2 + 8 + $h + $ht1 + $ht2 + $spacing*2, $white, $fontFolder.$textFont.$fontExt, $text ); imagejpeg( $fon, $demFile, 98 ); echo ("\r\nСохранено: " . $demFile . "\r\n"); imagecolordeallocate( $fon, $black ); imagecolordeallocate( $fon, $white ); imagedestroy( $fon );?>
Генератор на ПыхПых для быдлосайта
- Инклюдится к любому сайту
- Понимает JPG, GIF, PNG, BMP
- Впечатывает копирайт в нижнюю часть дема
<?phpfunction demotivator($image, $slogan1, $slogan2, $copyright) {// преобразование win в utf$slogan1 = dm_win2utf($slogan1);$slogan2 = dm_win2utf($slogan2);$copyright = dm_win2utf($copyright);$ext = getimagesize($image);// Открываем изображениеswitch($ext[2]) { case 2: {$img = ImageCreateFromJPEG($image); break;} case 1: {$img = ImageCreateFromGIF($image); break; } case 3: {$img = ImageCreateFromPNG($image); break;} case 6: {$img = ImageCreateFromBMP($image); break;} default : { unlink ($image); return 2; }}// Получение размеров изображения$x = ImageSX($img); // X$y = ImageSY($img); // Y// Размер черного прямоугольника, который будем рисовать$tx = $x * 0.1;$ty = $x * 0.1;$bx = $x + $tx;$by = $y + $ty;$dx= $x * 0.01; // Смещение. Необходимо для рисования рамки$dy= $x * 0.01;// Черный фон$black = ImageColorAllocate($img, 0, 0, 0);// Создаем новое изображение$img2 = ImageCreateTrueColor($bx + $tx, $by + $tx * 2.6);$black = ImageColorAllocate($img2, 0, 0, 0);// МасштабированиеImageCopyResized($img2, $img, $tx, $ty, 0, 0, $bx-$tx, $y, $x, $y);// Расчет смещений для рисования рамки$x1 = $tx;$y1 = $ty;$x2 = $bx;$y2 = $y + $ty;// Цвета рамки, слоганов и копирайта$col = ImageColorAllocate($img2, 255, 255, 255); // Цвет слоганов$col2 = ImageColorAllocate($img2, 100, 100, 100); // Цвет копирайта$col3 = ImageColorAllocate($img2, 255, 255, 255); // Цвет рамки// Рамки на изображенииImageRectangle($img2, $x1 - 5, $y1 - 5, $x2 + 4, $y2 + 4, $col3);ImageRectangle($img2, $x1 - 6, $y1 - 6, $x2 + 5, $y2 + 5, $col3);// Пишем слоганы, сначала с X=0, чтобы получить линейные размеры текста$s1 = ImageTTFText($img2, 0.06 * $bx, 0, $dx, $by + $ty, $col, "times.ttf", $slogan1);$s2 = ImageTTFText($img2, 0.035 * $bx, 0, $dx, $by + $ty + 0.08 * $bx, $col, "arial.ttf", $slogan2);// 1-й слоган не помещается в картинку - ошибка!if (($s1[2] - $s1[0]) > $bx + $tx) $sl1 = 1;$dx = (($bx + $tx) - ($s1[2] - $s1[0]))/2; // Смещение. Эта величина определяет центровку текста для 1-го слогана// Непосредственно текст. 1-й слоганImageFilledRectangle($img2, 0, $y2 + 10, $bx + $tx, $by + $tx * 2.8, $black);ImageTTFText($img2, 0.06 * $bx, 0, $dx, $by + 1.1*$ty, $col, "times.ttf", $slogan1);$dx = (($bx + $tx) - ($s2[2] - $s2[0]))/2; // Смещение. Эта величина определяет центровку текста для 2-го слогана// Непосредственно текст. 2-й слоган (таглайн)if ($dx < 0) { // Текст не умещается в картинку, масштабируем. $s = $s2[2] - $s2[0]; $size = (0.035 * $bx * $bx) /$s; $s2 = ImageTTFText($img2, $size, 0, $dx, $by + $ty + 0.08 * $bx, $col, "arial.ttf", $slogan2); $dx = (($bx + $tx) - ($s2[2] - $s2[0]))/2; ImageFilledRectangle($img2, 0, $by + 1.2* $tx, $bx + $tx, $by + $tx * 2.6, $black); ImageTTFText($img2, $size, 0, $dx, $by + $ty + 0.08 * $bx, $col, "arial.ttf", $slogan2);} else { $size = 0.035 * $bx; ImageFilledRectangle($img2, 0, $by + 1.4*$tx, $bx + $tx, $by + $tx * 2.3, $black); ImageTTFText($img2, $size, 0, $dx, $by + $ty + 0.08 * $bx, $col, "arial.ttf", $slogan2);}// CopyrightImageTTFText($img2, $size/1.7, 0, 10, $by + $tx * 2.5, $col2, "arial.ttf", $copyright);ImageJpeg($img2);ImageDestroy($img2);return 0;}function dm_win2utf($string){ if (function_exists("iconv")) { iconv("CP-1251","UTF-8",$string); return $string; } else { $out = ''; for ($i = 0; $i<strlen($string); ++$i){ $ch = ord($string{$i}); if ($ch < 0x80) $out .= chr($ch); else if ($ch >= 0xC0) if ($ch < 0xF0) $out .= "\xD0".chr(0x90 + $ch - 0xC0); // А-Я, а-п (A-YA, a-p) else $out .= "\xD1".chr(0x80 + $ch - 0xF0); // р-я (r-ya) else switch($ch){ case 0xA8: $out .= "\xD0\x81"; break; // YO case 0xB8: $out .= "\xD1\x91"; break; // yo // ukrainian case 0xA1: $out .= "\xD0\x8E"; break; // Ў (U) case 0xA2: $out .= "\xD1\x9E"; break; // ў (u) case 0xAA: $out .= "\xD0\x84"; break; // Є (e) case 0xAF: $out .= "\xD0\x87"; break; // Ї (I..) case 0xB2: $out .= "\xD0\x86"; break; // I (I) case 0xB3: $out .= "\xD1\x96"; break; // i (i) case 0xBA: $out .= "\xD1\x94"; break; // є (e) case 0xBF: $out .= "\xD1\x97"; break; // ї (i..) // chuvashian case 0x8C: $out .= "\xD3\x90"; break; // Ӑ (A) case 0x8D: $out .= "\xD3\x96"; break; // Ӗ (E) case 0x8E: $out .= "\xD2\xAA"; break; // Ҫ (SCH) case 0x8F: $out .= "\xD3\xB2"; break; // Ӳ (U) case 0x9C: $out .= "\xD3\x91"; break; // ӑ (a) case 0x9D: $out .= "\xD3\x97"; break; // ӗ (e) case 0x9E: $out .= "\xD2\xAB"; break; // ҫ (sch) case 0x9F: $out .= "\xD3\xB3"; break; // ӳ (u) } } return $out; }}?>
Урководство чайника
- Залить высер в отдельный php файл
- Приинклюдить его к проекту
- Не забыть залить в тот-же каталог шрифты times.ttf и arial.ttf
- Вызвать в нужном месте функцию demotivator(картинка, слоган, теглайн, копирайт);
- результат — картинка дема на экране браузера