Страница 1 из 2

Не отображает все картинки корректно

Добавлено: 30 окт 2014, 14:12
Леонид
Добрый день!

Есть отчёт со следующей структурой:

Page > DataBand > Image.

Далее из БД Oracle select'ом "вытягиваем" данные, где есть поле sertificate_body, представляющее массив byte[], но реально это обыкновенный jpeg.

В свойстве DataColumn компонента Image установлено поле из которого получаем данные. Всё работает и даже отображается.
Однако, при более подробном сравнении отображаемых данных и в полях таблицы базы данных есть различия, а именно - выводятся не все страницы.

Для примера я брал 182 страницы, каждая в среднем размеров 250Кб, итого около 40Мб.

Если запустить дизайнер и нажать Preview, то можно увитедь "Report Rendering Messages" такое сообщение для 82 картинок: "Expression in ImageData property of 'Image1' can't be evaluated!". В итоге, они отображаются как белые листы, хотя реально они есть.

Более того, если в источнике данных нажать "View data", то всё выбирается корректно, и можно увидеть даже все эти картинки в соответствующей колонке, однако при выводе компонент Image, выдаёт вышеописанное сообщение, а иногда даже "System.OutOfMemory". В последнем случае, программа занимает в памяти почему-то 1.5Gb, хотя реально там 40Mb всего, не ясно, но не суть.

Сразу оговорюсь, что пробовал все возможные способы решения проблемы, в т.ч. динамически создавал отчёт, - результаты те же.
Мало того, пробовал убирать из свойства DataColumn данные и прописывал такой код в событии GetImageData компонента Image:

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

System.IO.MemoryStream ms = new System.IO.MemoryStream(qrMain.SERTIFICATE_BODY);
System.Drawing.Image img = System.Drawing.Image.FromStream(ms);

e.Value = img;

ms.Dispose();
Не помогло, по-прежнему OutOfMemory.

Пробовал так:

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

e.Value = StiImageHelper.GetImageFromObject(qrMain.SERTIFICATE_BODY);
Тот же результат.

P.S. Отчёт во вложении.

Re: Не отображает все картинки корректно

Добавлено: 31 окт 2014, 16:01
HighAley
Здравствуйте.

Все картинки преобразуются в Bitmap и их размер возрастает на порядок. Откуда вы взяли размер отчёта в 40Мб?
Учитывая, что картинки на всё страницу, то они будет занимать достаточно много места.
Мы не можем воспроизвести вашу проблему без данных. Попробуйте использовать наш последний релиз.

Спасибо.

Re: Не отображает все картинки корректно

Добавлено: 31 окт 2014, 16:40
Леонид
Добрый вечер!

Приложил конкретный пример, который в событии GetImageData считывает последовательно 182 jpeg-файла из указанной директории (c:\temp) с именами 001.jpg, 002.jpg,...182.jpg. Все файлы изображений в отдельном архиве - положил на файлообменник http://rghost.ru/58811438, т.к. 40Мб почему-то не загружется корректно. То есть, это реальный пример, мы даже ничего не изменяли.
В какой-то момент происходит вызов исключения System.OutOfMemory и появляется красный крест в компоненте Image.

Версия StimulReport'а 2012.1.1300.0.

P.S. И да, не отчёт 40Мб, а файлы изображений. А если bmp, то понятно, что будет 400Мб после распаковки, а то и больше.

Re: Не отображает все картинки корректно

Добавлено: 03 ноя 2014, 09:18
Aleksey
Здравствуйте,

Не смогли воспроизвести проблему.
Пожалуйста, попробуйте последнюю версию. Так же попробуйте установить свойство ReportCacheMode для отчета.

Спасибо.

Re: Не отображает все картинки корректно

Добавлено: 05 ноя 2014, 10:47
Леонид
Доброе утро!

Скомпилировали проект под последнюю доступную версию - 2013.3.1800.0.
Запустили отчёт Сертификаты.mrt и 182 jpeg из директории c:\temp, чтобы отчёт выводил их по-порядку (см. предыдущий пост).

Выводы такие:

1) С установленным флажком ReportCacheMode в On - выводятся все изображения, но, если скроллить страницы вниз (кнопкой PageDown или колесом мышки), то примерно на 60-70-й возникает Exception.SystemOutOfMemory и перечёркнутый красный крест на отчёте;

2) Без установленного флажка ReportCacheMode (т.е. когда он Off) - выводятся не все изображения. Конкретно, в нашем случае и в конкретном примере со 117-й страницы идут пустые (белые) листы вместо сканов сертификатов.

Иными словами, от версии Стимула ничего неизменилось в данном конкретном баге, т.к. и на предыдущей и на последней версии всё работает одинаково.

Проверьте, пожалуйста, обе эти ситуации на конкретном отчёте и наших 182-х сканах.

Re: Не отображает все картинки корректно

Добавлено: 06 ноя 2014, 11:22
HighAley
Здравствуйте.

На данный момент последняя версия нашего продукта -- 2014.2.2000.
За последний год было сделано много оптимизаций. В том числе и в работе с кэшем.
Попробуйте скачать триальную версию и проверить данный отчёт с ней.

Спасибо.

Re: Не отображает все картинки корректно

Добавлено: 06 ноя 2014, 15:45
Леонид
Добрый день!

Провели много экспериментов на самом последнем билде - 2014.2.2000.0.

Результаты такие. В нашем проекте на последнем билде всё равно вылетает System.OutOfMemory exception, каждый раз по-разному, когда на 50-й, когда на 67-й странице, т.е. при простом скроллинге. Замечу, что при этом ReportCacheMode == On.

Специально создал рабочий пример отчёта с всё теми же 182 страницами, все они лежат в поддиректории Certificates проекта, и файл Certificates.mrt, который загружается динамически.

Какую корреляцию обнаружили. Если создавать отчёт так:

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

      StiReport report = new StiReport();
      report.Load("certificates.mrt");

      report.Dictionary.Variables["StartPath"].Value = programStartPath;
      report.Dictionary.Synchronize();
      report.Show();
То всё нормально работает, но только с включённым флагом ReportCacheMode == On.

Ошибка возникает (причём не всегда, - она не явная, т.е. иногда есть, иногда нет), когда отчёт создавать так:

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

      StiReport report = new StiReport();
      report.Load("certificates.mrt");

      report.Dictionary.Variables["StartPath"].Value = programStartPath;
      report.Dictionary.Synchronize();

      StiViewerControl stiPreview = new StiViewerControl()
      {
        Dock = DockStyle.Fill,
        Visible = true,

        // set option flags
        ShowPrint = true,
        ShowOpen = true,
        ShowEditor = true,
        ShowPageNew = true,
        ShowSendEMail = true,
        ShowThumbsPanel = true,
        ShowSaveDocumentFile = true,
      };

      // assign report object to preview control
      stiPreview.Report = report;
      stiPreview.FirstPage();
      stiPreview.SetZoom(100);

      this.Controls.Add(stiPreview); // add created preview control to the form
      this.WindowState = FormWindowState.Maximized; // set form maximized

      // start report
      report.Render();
Во втором случае, иногда приходится запускать отчёт 1-3 раза, чтобы получить ошибку. В этом случае ошибка выглядит так:

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

************** Текст исключения **************
System.ArgumentOutOfRangeException: Индекс за пределами диапазона. Индекс должен быть положительным числом, а его размер не должен превышать размер коллекции.
Имя параметра: index
   в System.Collections.CollectionBase.System.Collections.IList.get_Item(Int32 index)
   в Stimulsoft.Report.Engine.StiPageNumberCollection.get_Item(Int32 index)
   в Stimulsoft.Report.Engine.StiRenderProviderV2.IsFirstPage(StiReport report, StiPage page)
   в Stimulsoft.Report.Engine.StiRenderProviderV2.ProcessPageToCache(StiReport report, StiPage page, Boolean final)
   в Stimulsoft.Report.Components.StiPagesCollection.SavePage(StiPage page)
   в Stimulsoft.Report.Components.StiPagesCollection.AddPageToQuickCache(StiPage page, Boolean savePage)
   в Stimulsoft.Report.Components.StiPagesCollection.GetPage(StiPage page)
   в Stimulsoft.Report.Components.StiPagesCollection.get_Item(Int32 index)
   в Stimulsoft.Report.Viewer.StiViewerControl.GetVisiblePages()
   в Stimulsoft.Report.Viewer.StiViewerControl.view_MouseMove(Object sender, MouseEventArgs e)
   в System.Windows.Forms.Control.OnMouseMove(MouseEventArgs e)
   в System.Windows.Forms.Control.WmMouseMove(Message& m)
   в System.Windows.Forms.Control.WndProc(Message& m)
   в System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   в System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   в System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   в System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
и иногда следом за ней следует второй exception:

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

************** Текст исключения **************
System.NullReferenceException: Ссылка на объект не указывает на экземпляр объекта.
   в Stimulsoft.Report.Viewer.StiViewerControl.GetPageRect(StiPageParamView view)
   в Stimulsoft.Report.Viewer.StiViewerControl.view_MouseMove(Object sender, MouseEventArgs e)
   в System.Windows.Forms.Control.OnMouseMove(MouseEventArgs e)
   в System.Windows.Forms.Control.WmMouseMove(Message& m)
   в System.Windows.Forms.Control.WndProc(Message& m)
   в System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   в System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   в System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   в System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Отчёт (можно запустить без компиляции из директории \bin\Debug\) с исходными кодами по ссылке http://rghost.ru/58916091

Re: Не отображает все картинки корректно

Добавлено: 07 ноя 2014, 00:59
Jan
Здравствуйте,

Спасибо за баг-репорт. Нам нужно немножко времени на тест. Как только будут результаты мы сообщим Вам.

Спасибо.

Re: Не отображает все картинки корректно

Добавлено: 10 ноя 2014, 14:07
HighAley
Здравствуйте.

В момент присваивания отчёта вьюверу

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

stiPreview.Report = report;
рендеринг отчёта происходит автоматически.

Если вы делаете это ещё раз, то использование памяти увеличивается и могут возникнуть неизвестные баги.

Уберите вызов метода Render(); или перенесите его до создания вьювера.

Спасибо.

Re: Не отображает все картинки корректно

Добавлено: 10 ноя 2014, 15:03
Леонид
Добры день!

Проверил вашу рекомендацию, - к сожалению безрезультатно.

Если поставить код

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

report.Render();
выше

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

StiViewerControl stiPreview = new StiViewerControl()...
то отчёт рендерится так же - с ошибкой отсутствия памяти (OutOfMemoryException was handled).

Если код

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

report.Render();
убрать вообще, а оставить только

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

StiViewerControl stiPreview = new StiViewerControl()
{
....
}

stiPreview.Report = report;
То рендеринг и воовсе не происходит, - пишет 0 страниц.

Ещё мы заметили, что ошибка чаще возникает на компьютерах с 2-4Gb RAM, а там где 8-16Gb гораздо реже, что возможно связано с количество картинок (в данном случае 182).