Blog. Just Blog

Быстрый поиск

Введите фрагмент названия статьи для поиска

Оценка качества изображения для печати

15.10.2012 | Категория: Web-мастеру и не только | Автор: ManHunter

Оценка качества изображения для печати

Качество изображения измеряется в количествах пикселей (точек) на дюйм (1 дюйм = 25.4 мм), единица измерения - dpi (Dots Per Inch). К типографской печати обычно принимаются изображения не менее 150 dpi, а вот для фотопечати качество должно быть уже 300 dpi и больше. Однако, при оценке качества изображения обязательно надо учитывать и размер печати. К примеру, исходный файл из цифромыльницы с разрешением 1200х900 пикселов будет неплохо смотреться на фотокарточке 10х15 см, но для печати на плакате его качества будет недостаточно. А кадры с Nikon D800 разрешением 7360х4912 пикселов можно без проблем распечатать на формате A1 и повесить на стенку.

Для вычисления dpi надо желаемые размеры печати перевести в дюймы, а затем поделить разрешение исходного файла на эти значения по ширине и высоте. Полученные значения dpi и будут искомым результатом оценки качества изображения. Осталось оформить это все вот в такую несложную функцию:
  1. // Функция для расчета dpi изображения
  2. function get_dpi($picture$print_x$print_y) {
  3.     if (file_exists($picture)) {
  4.         list ($x,$y)=GetImageSize($picture);
  5.         if ($x && $y && $print_x && $print_y) {
  6.             // "Повернуть" изображение под размер печати
  7.             if ($print_x<$print_y) {
  8.                 if ($x>$y) {
  9.                     list ($x,$y)=array($y,$x);
  10.                 }
  11.             }
  12.             // Посчитать dpi по ширине и высоте
  13.             $dpi=array(
  14.                 'dpi_x'=>intval($x/($print_x/2.54)),
  15.                 'dpi_y'=>intval($y/($print_y/2.54))
  16.             );
  17.             return $dpi;
  18.         }
  19.         else {
  20.             return false;
  21.         }
  22.     }
  23.     else {
  24.         return false;
  25.     }
  26. }
Параметры функции: $picture - путь к файлу с изображением, $print_x - ширина печати в сантиметрах, $print_y - высота печати в сантиметрах. На выходе массив со значениями dpi по высоте и ширине для данного изображения или false, если файл отсутствует, имеет неправильный формат или заданы неправильные размеры печати. В случае необходимости изображение будет "повернуто" под размер печати.

Читать статью целиком »
Просмотров: 6639 | Комментариев: 2

Скрипт для проверки местонахождения и статуса посылок

21.06.2012 | Категория: Web-мастеру и не только | Автор: ManHunter
Для отслеживания почтовых отправлений на сайте Почты России сделана специальная страничка. Когда вы ждете одну-две посылки, то можно воспользоваться ей. Для автоматического отслеживания нескольких посылок также есть специальные сервисы, они самостоятельно опрашивают сайт Почты и сохраняют полученные результаты у себя в базе. Но для отслеживания большого числа посылок, как правило, на подобных сервисах требуется переходить на платные тарифы. Когда я столкнулся с такой ситуацией, то вариант с оплатой, естественно, сразу же был отвергнут как неприемлемый. Проще было самому написать некое подобие такого сервиса, но заточенного под свои нужды. Вот что у меня получилось:
  1. <?
  2. // Массив с трек-номерами посылок
  3. // заполняйте его по аналогии трек-номерами своих посылок
  4. $codes=array('RA111111111CN''RA222222222CN''RA33333333CN');
  5.  
  6. // Массив с результатами отслеживания
  7. $status=array();
  8.  
  9. $link='http://www.russianpost.ru/resp_engine.aspx?Path='.
  10.       'rp/servise/ru/home/postuslug/trackingpo';
  11.  
  12. foreach ($codes as $code) {
  13.     // Подготовка запроса cURL
  14.     $ch curl_init();
  15.     curl_setopt($chCURLOPT_URL$link);
  16.     curl_setopt($chCURLOPT_HEADER0);
  17.     curl_setopt($chCURLOPT_POST1);
  18.     curl_setopt($chCURLOPT_RETURNTRANSFER1);
  19.     curl_setopt($chCURLOPT_POSTFIELDS'entryBarCode='.$code.
  20.                 '&BarCode='.$code.'&searchsign=1');
  21.  
  22.     // Отправка POST-запроса на сервер и получение страницы результата
  23.     $grab=curl_exec($ch);
  24.  
  25.     if (eregi('value="([0-9]+)"',$grab,$pocket)) {
  26.         // установка URL и других необходимых параметров
  27.         curl_setopt($chCURLOPT_URL$link);
  28.         curl_setopt($chCURLOPT_HEADER1);
  29.         curl_setopt($chCURLOPT_POST1);
  30.         curl_setopt($chCURLOPT_RETURNTRANSFER1);
  31.         curl_setopt($chCURLOPT_POSTFIELDS'key='.$pocket[1]);
  32.  
  33.         // загрузка страницы
  34.         $grab=curl_exec($ch);
  35.  
  36.         // установка URL и других необходимых параметров
  37.         curl_setopt($chCURLOPT_URL$link);
  38.         curl_setopt($chCURLOPT_HEADER1);
  39.         curl_setopt($chCURLOPT_POST1);
  40.         curl_setopt($chCURLOPT_RETURNTRANSFER1);
  41.         curl_setopt($chCURLOPT_POSTFIELDS'entryBarCode='.$code.
  42.                     '&BarCode='.$code.'&searchsign=1');
  43.  
  44.         // загрузка страницы
  45.         $grab=curl_exec($ch);
  46.     }
  47.  
  48.     // Фикс кодировки полученной страницы
  49.     $grab=mb_convert_encoding($grab'Windows-1251''UTF-8');
  50.  
  51.     // Небольшой фикс для упрощения парсинга страницы
  52.     $grab=eregi_replace('<a href=javascript\:Wind\([^\(]*\)>','',$grab);
  53.  
  54.     preg_match_all('/<tr align="center"><td>([^<]+)<\/td><td>([^<]+)'.
  55.       '<\/td><td>[^<]*<\/td><td>([^<]+)<\/td><td>([^<]*)<\/td>/',$grab,$matches);
  56.  
  57.     $st=array();
  58.     $st['code']=$code;
  59.     // Если получен какой-то результат
  60.     if (count($matches[1])) {
  61.         // Последнее действие
  62.         if ($matches[4][count($matches[1])-1]) {
  63.             $st['action']=$matches[4][count($matches[1])-1];
  64.         }
  65.         else {
  66.             $st['action']=$matches[1][count($matches[1])-1];
  67.         }
  68.         // Дата последнего действия
  69.         $st['date']=$matches[2][count($matches[1])-1];
  70.         // Местонахождение посылки
  71.         $st['where']=$matches[3][count($matches[1])-1];
  72.     }
  73.     // Ошибка на сервере или статус посылки еще не определен
  74.     else {
  75.         $st['action']='Неизвестно';
  76.         $st['date']='--';
  77.         $st['where']='--';
  78.     }
  79.  
  80.     // Записать результат в массив
  81.     $status[]=$st;
  82.  
  83.     curl_close($ch);
  84. }
  85. // Теперь в массиве $status содержится информация по всем посылкам
  86. var_dump($status);
  87. ?>
Настраивать скрипт очень легко. В массив $codes по аналогии добавляете трек-номера своих посылок. Поддерживаются коды Международной почты (Universal Post Union) и внутренние номера отслеживания почты России. После этого скрипт можно заливать на сервер. Хостинг, где будет размещен скрипт, должен поддерживать cURL и обращение к удаленным серверам, но даже на минимальных тарифах на платных хостингах обычно с этим никаких проблем нет. Единственное ограничение - время выполнения скрипта, при опросе статуса очень большого количества посылок он может отваливаться по лимиту времени, установленному на хостинговом сервере. На практике статусы двух десятков посылок опрашиваются около 10 секунд.

Читать статью целиком »
Просмотров: 10573 | Комментариев: 20

Функция для отображения размера файла

21.05.2012 | Категория: Web-мастеру и не только | Автор: ManHunter
Размер файлов в PHP измеряется в байтах, но числа из большого количества цифр для восприятия очень неудобны. На мой взгляд гораздо нагляднее, если размер больших файлов будет отображаться в килобайтах, мегабайтах и так далее. Для этого я нарисовал вот такую вспомогательную функцию:
  1. function bytes2words($size) {
  2.     for($i=0$i<count($st=array('Кб','Мб','Гб')); $i++) {
  3.         if (($size/=1024)<1024) { $i++; break; }
  4.     }
  5.     return round($size,2).' '.$st[($i-1)];
  6. }
Результаты работы функции:
  1. echo bytes2words(1000).'<br>';              // 0.98 Кб
  2. echo bytes2words(10000).'<br>';             // 9.77 Кб
  3. echo bytes2words(100000).'<br>';            // 97.66 Кб
  4. echo bytes2words(1000000).'<br>';           // 976.56 Кб
  5. echo bytes2words(10000000).'<br>';          // 9.54 Мб
  6. echo bytes2words(100000000).'<br>';         // 95.37 Мб
  7. echo bytes2words(1000000000).'<br>';        // 953.67 Мб
  8. echo bytes2words(10000000000).'<br>';       // 9.31 Гб
  9. echo bytes2words(100000000000).'<br>';      // 93.13 Гб
  10. echo bytes2words(1000000000000).'<br>';     // 931.32 Гб
  11. echo bytes2words(10000000000000).'<br>';    // 9313.23 Гб
  12. echo bytes2words(100000000000000).'<br>';   // 93132.26 Гб
На перспективу можно учесть и терабайты (например, если надо считать не размер файлов, а магистральный трафик в датацентре), для этого в массив наименований надо просто добавить элемент 'Тб'. Тестовый вывод, соответственно, изменится следующим образом:
  1. echo bytes2words(100000000000).'<br>';      // 93.13 Гб
  2. echo bytes2words(1000000000000).'<br>';     // 931.32 Гб
  3. echo bytes2words(10000000000000).'<br>';    // 9.09 Тб
  4. echo bytes2words(100000000000000).'<br>';   // 90.95 Тб
Вспоминается шутка 90-х годов: "Сколько будет дважды два? - А мы покупаем или продаем?". Размер килобайта в функции указан как положено - 1024 байта, все результаты, соответственно, получаются из этого расчета. Если надо считать так, как это делают некоторые особо умные провайдеры, то замените в функции все значения 1024 на 1000.

Просмотров: 4596 | Комментариев: 4

Подсветка синтаксиса MySQL-запросов

07.04.2012 | Категория: Web-мастеру и не только | Автор: ManHunter
При выводе диагностики в своих рабочих проектах я использую вот такую функцию для подсветки синтаксиса MySQL-запросов. Она преобразует текст запроса, делая все служебные слова языка заглавными буквами и подсвечивает их цветом, а также выделяет различными цветами числовые значения и скобки. Такая подсветка позволяет сразу же увидеть синтаксические ошибки, да и вообще повышает наглядность сообщений при отладке скриптов.
  1. //-------------------------------------------------------------------
  2. // Функция подсветки синтаксиса MySQL-запроса
  3. // (C) ManHunter / PCL
  4. // http://www.manhunter.ru
  5. //-------------------------------------------------------------------
  6. function mysql_debug($query) {
  7.     $tmp=htmlspecialchars($query);
  8.     $tmp=str_replace("\r",'',$tmp);
  9.     $tmp=trim(str_replace("\n","\r\n",$tmp))."\r\n";
  10.  
  11.     $quote_list_text=array();
  12.     $quote_list_symbols=array();
  13.  
  14.     $k=0;
  15.     $quotes=Array();
  16.     // Обработать экранированные кавычки
  17.     preg_match_all("/\\\'|\\\&quot;/is"$tmp$quotes);
  18.     array_unique($quotes);
  19.     if (count($quotes)) {
  20.         foreach($quotes[0] as $i) {
  21.             $k++;
  22.             $quote_list_symbols[$k]=$i;
  23.             $tmp=str_replace($i'<symbol'.$k.'>'$tmp);
  24.         }
  25.     }
  26.  
  27.     $matches=Array(
  28.         "/(&quot;|'|`)(.*?)(\\1)/is"// текст в кавычках
  29.         "/\/\*.*?\*\//s",             // текст комментария
  30.         "/ \-\-.*\x0D\x0A/",          // текст ' --' комментария
  31.         "/ #.*\x0D\x0A/",             // текст ' #' комментария
  32.     );
  33.  
  34.     // Обработать текст
  35.     foreach($matches as $match) {
  36.         // Обработать текст
  37.         $found=array();
  38.         preg_match_all($match$tmp$found);
  39.         $quotes=(array)$found[0];
  40.         array_unique($quotes);
  41.         if (count($quotes)) {
  42.             foreach($quotes as $i) {
  43.                 $k++;
  44.                 $quote_list_text[$k]=$i;
  45.                 $tmp=str_replace($i'<text'.$k.'>'$tmp);
  46.             }
  47.         }
  48.     }    
  49.  
  50.     // Служебные слова MySQL
  51.     $keywords=Array(
  52.         "avg""as""auto_increment""and""analyze""alter",
  53.         "asc""all""after""add""action""against",
  54.         "aes_encrypt""aes_decrypt""ascii""abs""acos",
  55.         "asin""atan""authors""between""btree""backup",
  56.         "by""binary""before""binlog""benchmark""blob",
  57.         "bigint""bit_count""bit_or""bit_and""bin",
  58.         "bit_length""both""create""count""comment",
  59.         "check""char""concat""cipher""changed""column",
  60.         "columns""change""constraint""cascade""checksum",
  61.         "cross""close""concurrent""commit""curdate",
  62.         "current_date""curtime""current_time",
  63.         "current_timestamp""cast""convert""connection_id",
  64.         "coalesce""case""conv""concat_ws""char_length",
  65.         "character_length""ceiling""cos""cot""crc32",
  66.         "compress""delete""drop""default""distinct",
  67.         "decimal""date""describe""data""desc",
  68.         "dayofmonth""date_add""database""databases",
  69.         "double""duplicate""disable""datetime""dumpfile",
  70.         "distinctrow""delayed""dayofweek""dayofyear",
  71.         "dayname""day_minute""date_format""date_sub"
  72.         "decode""des_encrypt""des_decrypt""degrees",
  73.         "decompress""dec""engine""explain""enum",
  74.         "escaped""execute""extended""errors""exists",
  75.         "enable""enclosed""extract""encrypt""encode",
  76.         "elt""export_set""escape""exp""end""from",
  77.         "float""flush""fields""file""for""fast""full",
  78.         "fulltext""first""foreign""force""from_days"
  79.         "from_unixtime""format""found_rows""floor""field",
  80.         "find_in_set""group""grant""grants""global"
  81.         "get_lock""greatest""having""high_priority"
  82.         "handler""hour""hex""insert""into""inner"
  83.         "int""ifnull""if""isnull""in""infile""is"
  84.         "interval""ignore""identified""index""issuer"
  85.         "integer""is_free_lock""inet_ntoa""inet_aton"
  86.         "instr""join""kill""key""keys""left""load"
  87.         "local""limit""like""lock""lpad""last_insert_id"
  88.         "logs""length""longblob""longtext""last""lines"
  89.         "low_priority""locate""ltrim""leading""lcase"
  90.         "lower""load_file""ln""log""least""month""mod"
  91.         "max""min""mediumint""medium""master""modify"
  92.         "mediumblob""mediumtext""match""mode""monthname"
  93.         "mid""minute""master_pos_wait""make_set""null"
  94.         "not""now""none""new""numeric""no""natural"
  95.         "next""nullif""national""nchar""on""or"
  96.         "optimize""order""optionally""option""outfile"
  97.         "open""offset""outer""old_password""ord""oct"
  98.         "octet_length""primary""password""privileges"
  99.         "process""processlist""purge""partial""procedure",
  100.         "prev""period_add""period_diff""position""pow"
  101.         "power""pi""quick""quarter""quote""right"
  102.         "repair""restore""reset""regexp""references"
  103.         "replace""revoke""reload""require""replication"
  104.         "read""rand""rename""real""restrict"
  105.         "release_lock""rpad""rtrim""repeat""reverse"
  106.         "rlike""round""radians""rollup""select""sum"
  107.         "set""show""substring""smallint""super""subject"
  108.         "status""slave""session""start""share"
  109.         "straight_join""sql_small_result""sql_big_result"
  110.         "sql_buffer_result""sql_cache""sql_no_cache"
  111.         "sql_calc_found_rows""second""sysdate""sec_to_time"
  112.         "system_user""session_user""substring_index""std"
  113.         "stddev""soundex""space""strcmp""sign""sqrt"
  114.         "sin""straight""sleep""text""truncate""table"
  115.         "tinyint""tables""to_days""temporary""terminated"
  116.         "to""types""time""timestamp""tinytext"
  117.         "tinyblob""transaction""time_format""time_to_sec"
  118.         "trim""trailing""tan""then""update""union"
  119.         "using""unsigned""unlock""usage""use_frm"
  120.         "unix_timestamp""unique""use""user""ucase"
  121.         "upper""uuid""values""varchar""variables"
  122.         "version""variance""varying""where""with"
  123.         "warnings""write""weekday""week""when""xor"
  124.         "year""yearweek""year_month""zerofill");
  125.     $replace=Array();
  126.     foreach($keywords as $keyword) {
  127.         $replace[]='/\b'.$keyword.'\b/ie';
  128.     }
  129.  
  130.     // Выделить служебные слова в тексте запроса
  131.     $tmp=preg_replace($replace,
  132.         '"<b style=\"color:#0000FF\">".strtoupper("$0")."</b>"',$tmp);
  133.  
  134.     // Выделить числовые значения в тексте запроса
  135.     $tmp=preg_replace('/\b([\.0-9]+)\b/',
  136.         '<b style="color:#008000">\1</b>',$tmp);
  137.  
  138.     // Выделить скобки в тексте запроса
  139.     $tmp=preg_replace('/([\(\)])/',
  140.         '<b style="color:#FF0000">\1</b>',$tmp);
  141.  
  142.     // Вернуть обратно строки в кавычках
  143.     if (count($quote_list_text)) {
  144.         $quote_list_text=array_reverse($quote_list_texttrue);
  145.         foreach($quote_list_text as $k=>$i) {
  146.             $tmp=str_replace('<text'.$k.'>',
  147.                 '<span style="color:#777;">'.$i.'</span>'$tmp);
  148.         }
  149.     }
  150.     // Вернуть обратно экранированные символы
  151.     if (count($quote_list_symbols)) {
  152.         $quote_list_symbols=array_reverse($quote_list_symbolstrue);
  153.         foreach($quote_list_symbols as $k=>$i) {
  154.             $tmp=str_replace('<symbol'.$k.'>'$i$tmp);
  155.         }
  156.     }
  157.  
  158.     // Вернуть подсвеченный текст запроса
  159.     // Если не надо расставлять переносы, то уберите nl2br
  160.     return nl2br(trim($tmp));
  161. }
Единственный параметр функции $query - текст исходного запроса. На выходе подсвеченная строка запроса в формате HTML. Цвета подсветки захардкодены в исходнике, если надо, то поменяйте их на свои или вообще замените на определения стилей CSS.

Читать статью целиком »
Просмотров: 4703 | Комментариев: 7

Кэширование на PHP

02.03.2012 | Категория: Web-мастеру и не только | Автор: ManHunter
Кэширование данных - это особая технология, направленная на снижение нагрузки на сервер. Суть ее заключается в том, что динамический контент, выбранные из базы данные или данные, получаемые из сторонних источников, сохраняются на диске в виде обычного текстового файла или в памяти вашего сервера. Когда они потребуются снова, то уже нет необходимости опять выполнять тяжелый запрос к базе, обращаться к стороннему серверу или заново парсить шаблон страницы, достаточно просто прочитать эти данные из ранее сохраненного файла или из памяти. Такой подход позволяет значительно ускорить генерацию страниц и тем самым ускорить загрузку сайта, что немаловажно на нагруженных проектах. Актуальность закэшированных данных устанавливается параметром "жизни кэша", то есть интервалом времени от момента сохранения данных до момента, когда их требуется обновить. "Время жизни" определяется для каждого типа данных индивидуально. Так, например, текст статьи может больше никогда не меняться после опубликования, поэтому ее закэшированный вариант можно также никогда не обновлять, кэш с комментариями может обновляться по мере добавления комментариев, данные пузомерок Google PR и Яндекс тИЦ достаточно обновлять раз в сутки, а картинку счетчика посещений желательно перерисовывать с интервалом не реже 10 минут.

Сейчас мы попробуем написать свой модуль для работы с кэшем, основанный на файлах, чтобы понять как это все работает. Функции будут очень простые:
  1. // Определить папку для хранения кэшированных данных
  2. define ('CACHE_DIR',dirname(__FILE__).'/cache');
  3.  
  4. // Запись данных в кэш
  5. function save_cache($file$data) {
  6.     if ($f=fopen(CACHE_DIR.'/'.$file,'w')) {
  7.         fwrite($f,serialize($data));
  8.         fclose($f);
  9.         return true;
  10.     }
  11.     else {
  12.         return false;
  13.     }
  14. }
С записью проблем нет, мы просто создаем файл с заданным именем и записываем в него сериализованные данные. Чтение из кэша немного сложнее, так как сперва надо будет проверять наличие файла и, если требуется, его актуальность.

Читать статью целиком »
Просмотров: 6424 | Комментариев: 11

01 ... 13 14 15 16 17 18 19 ... 24
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.08 сек. / MySQL: 3 (0.0061 сек.) / Память: 4.5 Mb
Наверх