Ver Mensaje Individual
  #2 (permalink)  
Antiguo 21/04/2011, 10:36
Avatar de stramin
stramin
 
Fecha de Ingreso: marzo-2008
Ubicación: Cubil felino
Mensajes: 1.652
Antigüedad: 16 años, 9 meses
Puntos: 336
Respuesta: Caracteres especiales en imagen

ya encontré la santa solución y pondré la respuesta aquí por que se que mas de uno tendrá el mismo problema.

las 2 funciones para escribir caracteres con fuentes (imagettftext e imagefttext) no permiten caracteres que superen los 127 bytes (como tildes y eñes) y imprimen normalmente las codificaciones en otras palabras esta hecho para ingleses.

Por suerte en el manual de PHP alguien publicó una solución creada por el mismo (limalopex.eisfux.de), la función es la siguiente:

Código PHP:
Ver original
  1. define('EMPTY_STRING', '');
  2.  
  3.         function foxy_utf8_to_nce( $utf = EMPTY_STRING ) {
  4.           if($utf == EMPTY_STRING) return($utf);
  5.           $max_count = 5; // flag-bits in $max_mark ( 1111 1000 == 5 times 1)
  6.           $max_mark = 248; // marker for a (theoretical ;-)) 5-byte-char and mask for a 4-byte-char;
  7.           $html = EMPTY_STRING;
  8.           for($str_pos = 0; $str_pos < strlen($utf); $str_pos++) {
  9.             $old_chr = $utf{$str_pos};
  10.             $old_val = ord( $utf{$str_pos} );
  11.             $new_val = 0;
  12.             $utf8_marker = 0;
  13.             // skip non-utf-8-chars
  14.             if( $old_val > 127 ) {
  15.               $mark = $max_mark;
  16.               for($byte_ctr = $max_count; $byte_ctr > 2; $byte_ctr--) {
  17.                 // actual byte is utf-8-marker?
  18.                 if( ( $old_val & $mark  ) == ( ($mark << 1) & 255 ) ) {
  19.                   $utf8_marker = $byte_ctr - 1;
  20.                   break;
  21.                 }
  22.                 $mark = ($mark << 1) & 255;
  23.               }
  24.             }
  25.             // marker found: collect following bytes
  26.             if($utf8_marker > 1 and isset( $utf{$str_pos + 1} ) ) {
  27.               $str_off = 0;
  28.               $new_val = $old_val & (127 >> $utf8_marker);
  29.               for($byte_ctr = $utf8_marker; $byte_ctr > 1; $byte_ctr--) {
  30.                 // check if following chars are UTF8 additional data blocks
  31.                 // UTF8 and ord() > 127
  32.                 if( (ord($utf{$str_pos + 1}) & 192) == 128 ) {
  33.                   $new_val = $new_val << 6;
  34.                   $str_off++;
  35.                   // no need for Addition, bitwise OR is sufficient
  36.                   // 63: more UTF8-bytes; 0011 1111
  37.                   $new_val = $new_val | ( ord( $utf{$str_pos + $str_off} ) & 63 );
  38.                 }
  39.                 // no UTF8, but ord() > 127
  40.                 // nevertheless convert first char to NCE
  41.                 else {
  42.                   $new_val = $old_val;
  43.                 }
  44.               }
  45.               // build NCE-Code
  46.               $html .= '&#'.$new_val.';';
  47.               // Skip additional UTF-8-Bytes
  48.               $str_pos = $str_pos + $str_off;
  49.             }
  50.             else {
  51.               $html .= chr($old_val);
  52.               $new_val = $old_val;
  53.             }
  54.           }
  55.           return($html);
  56.         }

Para llamar a la función previamente se debe decodificar las entidades HTML, así que recomiendo llamarla así:

Código PHP:
Ver original
  1. foxy_utf8_to_nce(html_entity_decode(&#237;));

y listo, la funcion convierte a unicode numerico de HTML el caracter desde ascii para ambos de mas de 127 bytes (UTF-8 + ANSI)