Перейти к содержанию
Fire Monkey от А до Я
  • 0

Ошибка "Bitmap size too big"


Евгений Корепов

Вопрос

На незначительном количестве устройств, менее 0,1%, получаю ошибку "Bitmap size too big" при AImage.Bitmap.LoadFromStream(AMemoryStream). Подозреваю что ошибка происходит на слабых устройствах. Картинка 250х250 png. Код выполняется в основном потоке (в интернетах были упоминания что глючит эта операция в отдельном потоке на каких то версиях Delphi).

Как предотвратить подобное? Можно как то определить максимальный размер картинки для текущего устройства? Или может дело не в свободной памяти, а в чем то еще?

Ссылка на комментарий

Рекомендуемые сообщения

  • 0
1 час назад, tromani сказал:

хм... ну очевидно что медленность работы вызвана 


ABitmapSurfaceResize.StretchFrom(ABitmapSurface,mxW,mxH);

в любом случае, поменяй код так чтоб эта часть вызывалась только тогда когда надо, в ином случае делай .Assign это решит проблему.

 

Я конечно не знаю как у вас происходит но меня очень напрягает когда 2-3% скачавших приложение ставят оценку 1 потому что что-то не заработало или они не разобрались как работает

 

 

В исходниках уже проделывается все что есть в вашем коде, посмотрите внимательно. У меня ошибка появляется в моем коде

Else
    if Assigned(ABitmap) then
      ABitmap.Assign(ABitmapSurface);

т.е. когда вроде как не требуется уменьшать изображение, т.е. ошибка появляется где то в этом коде исходников:

begin
    SetSize(Source.Width, Source.Height);
    if Map(TMapAccess.Write, BitmapData) then
    try
      for I := 0 to TBitmapSurface(Source).Height - 1 do
        Move(TBitmapSurface(Source).Scanline[I]^, BitmapData.GetScanline(I)^, BitmapData.BytesPerLine);
    finally
      Unmap(BitmapData);
    end;
  end;

 

Ссылка на комментарий
  • 0

попробуем продолжить, на стареньком но не очень уж мертвом устройстве загрузка файла происходит катострофически невероятно долго. нашел более менее нормальный по скорости способ. но и тут не так все хорошо может ктото поймет в чем дело:

procedure JBitmapToBitmap(const AImage: JBitmap; const ResBitmap: TBitmap);
var
  ImageData: TJavaArray<Integer>;
  BitmapData: TBitmapData;
  Width, Height: Integer;
begin
  Width := AImage.getWidth;
  Height := AImage.getHeight;
  try
    ImageData := TJavaArray<Integer>.Create(Width * Height);
    ResBitmap.SetSize(Width,Height);
    AImage.getPixels(ImageData, 0, Width, 0, 0, Width, Height);
    if ResBitmap.Map(TMapAccess.maWrite, BitmapData) then
      try
        Move(ImageData.Data^, BitmapData.Data^, Width * Height * SizeOf(Integer));
      finally
        ResBitmap.Unmap(BitmapData);
      end else
        ResBitmap.Clear(TAlphaColorRec.Green);
  except
    ResBitmap.Clear(TAlphaColorRec.Green);
  end;
end;
    
function calculateInSampleSize(options:JBitmapFactory_Options; reqWidth, reqHeight:integer):integer;
var
  nh,nw:integer;
  heightRatio,widthRatio:integer;
begin
  nh:=options.outHeight;
  nw:=options.outWidth;
  result:=1;
  if (nh> reqHeight) or (nw > reqWidth) then
  begin
    heightRatio:=round( nh / reqHeight);
    widthRatio:= round(nw /reqWidth);
    if heightRatio<widthRatio then
      Result:=heightRatio else
        Result:=widthRatio;
  end;
end;

var
  cur_bitmap:JBitmap;
  bitmap_option:JBitmapFactory_Options;
  cf_path:string;
begin
  bitmap_option:=TJBitmapFactory_Options.JavaClass.init;
  bitmap_option.inJustDecodeBounds := true;
  TJBitmapFactory.JavaClass.decodeFile(StringToJString(cf_path),bitmap_option);
  bitmap_option.inSampleSize := calculateInSampleSize(bitmap_option, Round(Image5.Width), Round(Image5.Height));
  bitmap_option.inJustDecodeBounds := false;
  try
    cur_bitmap:=TJBitmapFactory.JavaClass.decodeFile(StringToJString(cf_path),bitmap_option);
  except
    cur_bitmap:=nil;
  end;
  if Assigned(cur_bitmap) then
    JBitmapToBitmap(cur_bitmap,Image5.Bitmap);
end;

таким образом все просто шикарно, загрузка мгновенно все норм кроме одного, вместо синего - красный, не знаю как решить

Ссылка на комментарий
  • 0

в общем вышел из положения, очередным костылем к FMX, если кому понадобиться вот полный текст, работает сносно

procedure JBLoadFromFile(FileName:string; const ABitmap : TBitmap;W,H:integer);

  procedure SwapRB(var src:TJavaArray<Integer>);
  var
    i:integer;
  begin
	  for i:= 0 to src.Length-1 do
      src.Items[i]:=(src.Items[i] and $FF00FF00) or ((src.Items[i] and $000000FF) shl 16) or
        ((src.Items[i] and $00FF0000) shr 16);
  end;

  procedure JBitmapToBitmap(const AImage: JBitmap; const ResBitmap: TBitmap);
  var
    ImageData: TJavaArray<Integer>;
    BitmapData: TBitmapData;
    Width, Height: Integer;
  begin
    Width := AImage.getWidth;
    Height := AImage.getHeight;
    try
      ResBitmap.SetSize(Width,Height);
      ImageData := TJavaArray<Integer>.Create(Width * Height);
      AImage.getPixels(ImageData, 0, Width, 0, 0, Width, Height);
      SwapRB(ImageData);
      if ResBitmap.Map(TMapAccess.maWrite, BitmapData) then
      try
        Move(ImageData.Data^, BitmapData.Data^, Width * Height * SizeOf(Integer));
      finally
        ResBitmap.Unmap(BitmapData);
      end else
        ResBitmap.Clear(TAlphaColorRec.Green);
    except
      ResBitmap.Clear(TAlphaColorRec.Green);
    end;
  end;

  function calculateInSampleSize(options:JBitmapFactory_Options; reqWidth, reqHeight:integer):integer;
  var
    nh,nw:integer;
    heightRatio,widthRatio:integer;
  begin
    nh:=options.outHeight;
    nw:=options.outWidth;
    result:=1;
    if (nh> reqHeight) or (nw > reqWidth) then
    begin
      heightRatio:=round( nh / reqHeight);
      widthRatio:= round(nw /reqWidth);
      if heightRatio<widthRatio then
        Result:=heightRatio else
        Result:=widthRatio;
    end;
  end;

var
  bmf_options:JBitmapFactory_Options;
  cbm:JBitmap;
begin
  bmf_options:=TJBitmapFactory_Options.JavaClass.init;
  bmf_options.inJustDecodeBounds := true;
  TJBitmapFactory.JavaClass.decodeFile(StringToJString(FileName),bmf_options);
  bmf_options.inSampleSize := calculateInSampleSize(bmf_options, W, H);
  bmf_options.inJustDecodeBounds := false;
  try
    cbm:=TJBitmapFactory.JavaClass.decodeFile(StringToJString( FileName),bmf_options);
  except
    cbm:=nil;
  end;
  if Assigned(cbm) then
    try
      JBitmapToBitmap(cbm,ABitmap)
    except
      ABitmap.Clear(TAlphaColorRec.Blue);
    end else
      ABitmap.Clear(TAlphaColorRec.Green);
end;

может кто улучшит, подскажет чтото новое

 

Ссылка на комментарий
  • 0

У меня эта ошибка возникает на этапе работы с IDE. Причем вообще непонятно на что ругается. Самая большая картинка в проекте это стиль в TStyleBook. Причем радикально ничего не менялось в проекте, но в определенный момент ошибка стала выскакивать в виде диалогового окна при навигации по форме. 

Ссылка на комментарий
  • 0
  • Администраторы
15 часов назад, Alex Bakulin сказал:

У меня эта ошибка возникает на этапе работы с IDE. Причем вообще непонятно на что ругается. Самая большая картинка в проекте это стиль в TStyleBook. Причем радикально ничего не менялось в проекте, но в определенный момент ошибка стала выскакивать в виде диалогового окна при навигации по форме. 

Я думаю, надо попробовать отключить пакет в среде MultiDevicePreview. Он может быть причиной этой ошибки.

Ссылка на комментарий
  • 0
1 час назад, Brovin Yaroslav сказал:

Я думаю, надо попробовать отключить пакет в среде MultiDevicePreview. Он может быть причиной этой ошибки.

Я в Project - Options - Package не нашел этого для Berlin. Не там смотрю? Или не так ищу?

Ссылка на комментарий
  • 0
  • Модераторы
9 часов назад, Alex Bakulin сказал:

Я в Project - Options - Package не нашел этого для Berlin. Не там смотрю? Или не так ищу?

 

Тормозит IDE:

В 09.11.2016 в 11:45, Andrey Efimov сказал:

Ну если это тот же баг, что словил я, то вам однозначно помогут такие действия (рекомендация от Ярослава, по конкретно моему багу):

1) Закрываем студию, так чтобы в диспетчере задач не было процесса "bds.exe"

2) Идём в папку C:\Program Files\Embarcadero\Studio\18.0\bin, находим там файл MultidevicePreview240.bpl

3) Переименовываем его в !MultidevicePreview240.bpl

4) Запускаем студию и проверяем (если не поможет, то переименуйте файл обратно)

 

p.s. Вот мой багрепорт https://quality.embarcadero.com/browse/RSP-15992

 

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...