Получения изображения

Здесь обсуждаются технические аспекты создания дополнений.
Kbrais
Сообщения: 3
Зарегистрирован: 22:29, 02.08.2012

Получения изображения

Сообщение Kbrais » 22:33, 02.08.2012

Код: Выделить всё

function fReadJpegImage(bInBuffer: PAnsiChar; var iOffset: Integer): TJpegImage;

var
  JpegStream: TJpegStream;
  DataSize: DWord;
begin
  JpegStream := TJpegStream.Create;
  try
    DataSize := PDWORD(bInBuffer)^;
    Inc(bInBuffer, SizeOf(DWord));
    JpegStream.SetPointer(bInBuffer, DataSize);
    Result := TJpegImage.Create;
    try
       Result.LoadFromStream(JpegStream);
       Inc(iOffset, DataSize);
    except
       Result.Free;
       raise;
    end;
  finally
    JpegStream.Free;
  end;
end;
Составил функцию но нечего не выходит! Может кто знает в чём проблема?

KGB
Сообщения: 659
Зарегистрирован: 08:54, 13.07.2010
Откуда: Чебоксары, Россия
Контактная информация:

Re: Получения изображения

Сообщение KGB » 23:51, 02.08.2012

Что-то мне подсказывает, что чтение начинается не с того адреса (bInBuffer разве не на начало буфера указывает? если да, то надо учитывать iOffset).

Kbrais
Сообщения: 3
Зарегистрирован: 22:29, 02.08.2012

Re: Получения изображения

Сообщение Kbrais » 00:04, 03.08.2012

Можно пример учёта!?

KGB
Сообщения: 659
Зарегистрирован: 08:54, 13.07.2010
Откуда: Чебоксары, Россия
Контактная информация:

Re: Получения изображения

Сообщение KGB » 00:08, 03.08.2012

Код: Выделить всё

function fReadJpegImage(bInBuffer: PAnsiChar; var iOffset: Integer): TJpegImage;

var
  JpegStream: TJpegStream;
  DataSize: DWord;
begin
  JpegStream := TJpegStream.Create;
  try
    bInBuffer := bInBuffer + iOffset;
    DataSize := PDWORD(bInBuffer)^;
    Inc(bInBuffer, SizeOf(DWord));
    JpegStream.SetPointer(bInBuffer, DataSize);
    Result := TJpegImage.Create;
    try
       Result.LoadFromStream(JpegStream);
       Inc(iOffset, DataSize + 4);
    except
       Result.Free;
       raise;
    end;
  finally
    JpegStream.Free;
  end;
end;

Проверять сейчас не на чем, поэтому пример привел без проверки.

Kbrais
Сообщения: 3
Зарегистрирован: 22:29, 02.08.2012

Re: Получения изображения

Сообщение Kbrais » 00:18, 03.08.2012

Теперь всё работает. Спасибо!

Аватара пользователя
Jenya-Grin
Сообщения: 356
Зарегистрирован: 20:30, 22.09.2011
Откуда: Украина, г.Бердичев

Re: Получения изображения

Сообщение Jenya-Grin » 04:55, 29.08.2012

В этом посте я приводил нерабочий код и просил помощи у Максима.
Но сумел решить сам.
Готовенькое - ниже! :mrgreen:
Последний раз редактировалось Jenya-Grin 05:26, 29.08.2012, всего редактировалось 1 раз.

Аватара пользователя
Jenya-Grin
Сообщения: 356
Зарегистрирован: 20:30, 22.09.2011
Откуда: Украина, г.Бердичев

Получения изображения [РЕШЕНО C++]

Сообщение Jenya-Grin » 05:21, 29.08.2012

:!: :!: :!: :!: :!: :!: :!: :!: :!: :!: :!: :!:

Часов 7 бился, и всётаки решилось.

100% рабочий код получения изображения на C++ :

Функция чтения данных из буфера:

Код: Выделить всё

AnsiString fReadAnsi(BYTE * bInBuffer, int * iOffset)
{
   int iLength;
   memcpy(&iLength, bInBuffer + (*iOffset),4);
   (*iOffset)+=4;
   AnsiString uRet;
   uRet.SetLength(iLength);
   memcpy(uRet.c_str(), bInBuffer + (*iOffset),iLength*2);
   (*iOffset)+=iLength*2;
   return uRet;
}


Инициализация события, чтение данных:

Код: Выделить всё

   if(dwID==1070) //сообщение в общий канал // ПЛАГИН СЕРВЕРНЫЙ !!!
   {
      UnicodeString uVirtualUserLogin = fReadText(bInBuffer, &iReadOffset);
      UnicodeString uSenderLogin = fReadText(bInBuffer, &iReadOffset);
      UnicodeString uSenderIP = fReadText(bInBuffer, &iReadOffset);
      int iSenderIcon = fReadInteger(bInBuffer, &iReadOffset);
      UnicodeString uChannel = fReadText(bInBuffer, &iReadOffset);
      int iMessageMode = fReadInteger(bInBuffer, &iReadOffset);
      TxtMsg = fReadText(bInBuffer, &iReadOffset);

      if ( TxtMsg == "[image]" )
      {
         AnsiString imgData = fReadAnsi(bInBuffer, &iReadOffset);

         GetImg(imgData);
      }
   }


Преобразование из AnsiString в JPG и сохранение:

Код: Выделить всё

void GetImg(AnsiString iData)
{
   TJPEGImage *J = new TJPEGImage;
   TMemoryStream * ms1 = new TMemoryStream;
   ms1->Write((iData).c_str(),(iData).Length());
   ms1->Position = 0;
   J->LoadFromStream(ms1);
   delete ms1;

   J->SaveToFile("C:\\Documents and Settings\\1234\\Рабочий стол\\ax.jpg");
}


Ура! ура! ура! :!: :wink: 8-) :D :D

Аватара пользователя
Jenya-Grin
Сообщения: 356
Зарегистрирован: 20:30, 22.09.2011
Откуда: Украина, г.Бердичев

Re: Получения изображения

Сообщение Jenya-Grin » 09:52, 30.08.2012

С JPG и BMP всё отлично, однако при поступлении PNG изображения
сервер зависает вот после этих строк:

Код: Выделить всё

AnsiString fReadAnsi(BYTE * bInBuffer, int * iOffset)
{
   int iLength;
   memcpy(&iLength, bInBuffer + (*iOffset),4);



Если уж никак с PNG не решить, подскажите хотябы как сделать так чтоб не зависал.
тогда уже и исключение можно делать, оповещать что PNG например неподходит..

Maxim Mirgorodsky
Администратор
Сообщения: 6731
Зарегистрирован: 09:56, 27.06.2005
Благодарил (а): 1 раз

Re: Получения изображения

Сообщение Maxim Mirgorodsky » 18:22, 30.08.2012

Данный код не относится к PNG. Проверьте, есть ли действительно в буфере данные после iOffset.

Аватара пользователя
Jenya-Grin
Сообщения: 356
Зарегистрирован: 20:30, 22.09.2011
Откуда: Украина, г.Бердичев

Re: Получения изображения [РЕШЕНО C++]

Сообщение Jenya-Grin » 05:08, 19.10.2012

Jenya-Grin писал(а)::!: :!: :!: :!: :!: :!: :!: :!: :!: :!: :!: :!:

Функция чтения данных из буфера:

Код: Выделить всё

AnsiString fReadAnsi(BYTE * bInBuffer, int * iOffset)
{
   int iLength;
   memcpy(&iLength, bInBuffer + (*iOffset),4);
   (*iOffset)+=4;
   AnsiString uRet;
   uRet.SetLength(iLength);
   memcpy(uRet.c_str(), bInBuffer + (*iOffset),iLength*2);
   (*iOffset)+=iLength*2;
   return uRet;
}


Инициализация события, чтение данных:

Код: Выделить всё

   if(dwID==1070) //сообщение в общий канал // ПЛАГИН СЕРВЕРНЫЙ !!!
   {
      UnicodeString uVirtualUserLogin = fReadText(bInBuffer, &iReadOffset);
      UnicodeString uSenderLogin = fReadText(bInBuffer, &iReadOffset);
      UnicodeString uSenderIP = fReadText(bInBuffer, &iReadOffset);
      int iSenderIcon = fReadInteger(bInBuffer, &iReadOffset);
      UnicodeString uChannel = fReadText(bInBuffer, &iReadOffset);
      int iMessageMode = fReadInteger(bInBuffer, &iReadOffset);
      TxtMsg = fReadText(bInBuffer, &iReadOffset);

      if ( TxtMsg == "[image]" )
      {
         AnsiString imgData = fReadAnsi(bInBuffer, &iReadOffset);

         GetImg(imgData);
      }
   }


Преобразование из AnsiString в JPG и сохранение:

Код: Выделить всё

void GetImg(AnsiString iData)
{
   TJPEGImage *J = new TJPEGImage;
   TMemoryStream * ms1 = new TMemoryStream;
   ms1->Write((iData).c_str(),(iData).Length());
   ms1->Position = 0;
   J->LoadFromStream(ms1);
   delete ms1;

   J->SaveToFile("C:\\Documents and Settings\\1234\\Рабочий стол\\ax.jpg");
}






Если постить маленькое изображение весом, то сохраняется.
Если например 10кб, то зависает вот в этой функции:

Код: Выделить всё

AnsiString fReadAnsi(BYTE * bInBuffer, int * iOffset)
{
   int iLength;
   memcpy(&iLength, bInBuffer + (*iOffset),4);
   (*iOffset)+=4;
   AnsiString uRet;
   uRet.SetLength(iLength);
   memcpy(uRet.c_str(), bInBuffer + (*iOffset),iLength*2);
   (*iOffset)+=iLength*2;
   return uRet;
}


Maxim Mirgorodsky, в чём может быть проблема?

Maxim Mirgorodsky
Администратор
Сообщения: 6731
Зарегистрирован: 09:56, 27.06.2005
Благодарил (а): 1 раз

Re: Получения изображения

Сообщение Maxim Mirgorodsky » 12:57, 22.10.2012

memcpy(uRet.c_str(), bInBuffer + (*iOffset),iLength*2);
(*iOffset)+=iLength*2;


В этих строках ошибка. Если Вы читаете байты, то почему iLength*2?

Правильно:

memcpy(uRet.c_str(), bInBuffer + (*iOffset),iLength);
(*iOffset)+=iLength;

Аватара пользователя
Jenya-Grin
Сообщения: 356
Зарегистрирован: 20:30, 22.09.2011
Откуда: Украина, г.Бердичев

Re: Получения изображения

Сообщение Jenya-Grin » 03:49, 23.10.2012

Maxim Mirgorodsky писал(а):memcpy(uRet.c_str(), bInBuffer + (*iOffset),iLength*2);
(*iOffset)+=iLength*2;


В этих строках ошибка. Если Вы читаете байты, то почему iLength*2?

Правильно:

memcpy(uRet.c_str(), bInBuffer + (*iOffset),iLength);
(*iOffset)+=iLength;


Большое спасибо. Проблема решена :D

Ответить