Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Delphi: Общие вопросы > Проблема с перекодировкой UTF8 в Ansi


Автор: snakess 14.06.18, 07:39
Доброго времени суток!
Получаю электронные письма через Indy
в теле письма проверяю на кодировку utf-8 и вызываю UTF8ToAnsi

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
      ...
      if AnsiUpperCase(fMail.CharSet)='UTF-8' Then fBody.Text:=UTF8ToAnsi(fMail.Body.Text)
      Else fBody.text:=fMail.Body.text;
      ...


Все прекрасно работает, но если в теле письма, обычно в афтарсокой подписи, содержатся символы-картинки, то
функция UTF8ToAnsi выдает пустую строку. Как только я удаляю руками эти символы, то функция прекрасно перекодирует все письмо.
Например, есть подпись
в utf-8 выглядит как Angelina????ᴾᴴᴼᵀᴼᴳᴿᴬᴾᴴᴱᴿ????
при просмотре в ansi выглядит как Angelina🍦ᴾᴴᴼᵀᴼᴳᴿᴬᴾᴴᴱᴿ🍦

вот из-за этих ????ᴾᴴᴼᵀᴼᴳᴿᴬᴾᴴᴱᴿ????
UTF8ToAnsi и косячит, выдавая пустой текст письма.

Подскажите, как вырезать такие вот украшательства из текста :-? ?, они мне не нужны для дальнейшей обработки письма >:( .

Автор: snakess 14.06.18, 10:20
Получилось преобразовать. Может кому понадобится :) размещаю тут код.

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    function FromUTF8 (const Src: String): WideString;
     var a,b,c: char;
         i,j: Integer;
     
    begin
      i:=1; j:=1;
      SetLength(result,length(src));
      while i<=length(src) do
      begin
        a:=src[i]; Inc(i);
        if byte(a)<$80 then
        begin
            result[j]:=wchar(a);
            Inc(j);
            continue;
        end;
        if i>length(src) then break;
        b:=src[i]; Inc(i);
        if (byte(a)<$E0) or (i>length(src)) then
        begin
            result[j]:=wchar(((byte(a) and $1F) shl 6) or (byte(b) and $3F));
            Inc(j);
            continue;
        end;
        c:=src[i]; Inc(i);
        result[j]:=wchar(((byte(a) and $F) shl 12) or ((byte(b) and $3F) shl 6) or (byte(c) and $3F));
        Inc(j);
      end;
      SetLength(result,j-1);
     
    end;
     
    function WideStringToString(const ws: WideString; codePage: Word): AnsiString;
    var
      l: integer;
    begin
      if ws = '' then
        Result := ''
    else
      begin
        l := WideCharToMultiByte(codePage,
          WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,
          @ws[1], -1, nil, 0, nil, nil);
        SetLength(Result, l - 1);
        if l > 1 then
          WideCharToMultiByte(codePage,
            WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,
            @ws[1], -1, @Result[1], l - 1, nil, nil);
      end;
    end;
     
    function UTf8(Src:String):String;
    var st:String;
        wd:WideString;
    Begin
     st:='';
     st:=UTF8ToAnsi(Src);
     if st='' Then
      Begin
        wd:=FromUTF8(Src);
        st:=WideStringToString(wd,1251);
        st:=ReplaceStr(st,'?','');
      End;
     result:=st;
    End;
    ......




в основной процедуре, вызываю UTF8(fMail.Body.text), если CharSet установлен в UTF8

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)