Здесь есть пара возможностей (и, пожалуйста, опубликуйте весь класс, если это не так).
1) Вы не инициализируете изображение правильно. 2) Ваш поток пуст, поэтому вы ничего не получаю
Я предполагаю, что student.getImage () имеет подпись байта [], поэтому сначала убедитесь, что эти данные фактически нетронуты и представляют изображение. Во-вторых - вы не указываете тип контента, который должен быть «image / jpg» или все, что вы используете.
Вот некоторый код шаблона, чтобы проверить его, я использую для этого Primefaces 2.
/** 'test' package with 'test/test.png' on the path */
@RequestScoped
@ManagedBean(name="imageBean")
public class ImageBean
{
private DefaultStreamedContent content;
public StreamedContent getContent()
{
if(content == null)
{
/* use your database call here */
BufferedInputStream in = new BufferedInputStream(ImageBean.class.getClassLoader().getResourceAsStream("test/test.png"));
ByteArrayOutputStream out = new ByteArrayOutputStream();
int val = -1;
/* this is a simple test method to double check values from the stream */
try
{
while((val = in.read()) != -1)
out.write(val);
}
catch(IOException e)
{
e.printStackTrace();
}
byte[] bytes = out.toByteArray();
System.out.println("Bytes -> " + bytes.length);
content = new DefaultStreamedContent(new ByteArrayInputStream(bytes), "image/png", "test.png");
}
return content;
}
}
и некоторая разметка ...
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui"
>
<h:head>
</h:head>
<h:body>
<p:graphicImage value="#{imageBean.content}" />
</h:body>
</html>
Если этот код работает, то вы настроены правильно. Несмотря на то, что это код мусора для потоков (не используйте его в процессе производства) , он должен дать вам возможность устранить неисправность. Я предполагаю, что вы можете что-то происходить в вашей JPA или другой базе данных, где вы байт [] пуст или он отформатирован неправильно. Кроме того, у вас может быть проблема с контентом.
Наконец, я бы клонировал данные из компонента, чтобы student.getImage () был только скопирован в новый массив, а затем использован. Таким образом, если у вас что-то неизвестное происходит (что-то еще перемещает объект или меняет байт [], вы не возитесь с вашими потоками.
Сделайте что-то вроде:
byte[] data = new byte[student.getImage().length]
for(int i = 0; i < data.length; i++)
data[i] = student.getImage()[i];
, так что ваш bean-экземпляр имеет копию (или Arrays.copy () - независимо от того, что плавает ваша лодка). Я не могу подчеркнуть, что что-то простое, как этот / тип содержимого, как правило, неверно. Удачи вам.
Диапазон двойных является путем, больше, чем диапазон целых чисел на 32 или 64 бита, который является почему std::floor
возвраты double
. Кастинг к int
должен быть прекрасным, пока это в соответствующем диапазоне - но знать, что double
не может представить все целые числа на 64 бита точно, таким образом, можно также закончить с ошибками, когда Вы идете вне точки, в которой точность double
такова, что различие между двумя последовательными удваивается, больше, чем 1.
Если Вы хотите иметь дело с различными числовыми условиями и хотеть обработать различные типы преобразований управляемым способом, то, возможно, необходимо посмотреть эти Повышение. NumericConversion. Эта библиотека позволяет обрабатывать странные случаи (как из диапазона, округление, диапазоны, и т.д.)
Вот пример из документации:
#include <cassert>
#include <boost/numeric/conversion/converter.hpp>
int main() {
typedef boost::numeric::converter<int,double> Double2Int ;
int x = Double2Int::convert(2.0);
assert ( x == 2 );
int y = Double2Int()(3.14); // As a function object.
assert ( y == 3 ) ; // The default rounding is trunc.
try
{
double m = boost::numeric::bounds<double>::highest();
int z = Double2Int::convert(m); // By default throws positive_overflow()
}
catch ( boost::numeric::positive_overflow const& )
{
}
return 0;
}
Большая часть стандартного математического использования библиотеки удваивает, но обеспечивает версии плавающие также. станд.:: floorf () является версией одинарной точности станд.:: пол (), если Вы предпочли бы не использовать, удваивается.
Редактирование: я удалил часть своего предыдущего ответа. Я заявил, что пол был избыточен при кастинге к интервалу, но я забыл, что это только верно для положительных чисел с плавающей точкой.
static_cast <int> (std::floor(x));
делает в значительной степени, что Вы хотите, да. Это дает Вам ближайшее целое число, округленное к - бесконечность. По крайней мере, пока Ваш вход находится в диапазоне, представимом ints. Я не уверен, что Вы подразумеваете 'под добавлением.5 и этажеркой, но это не будет иметь того же эффекта
И станд.:: пол возвращает двойное, потому что это является самым общим. Иногда Вы могли бы хотеть округлить плавание или удвоиться, но сохранить тип. Таким образом, раунд 1.3f к 1.0f, а не к 1.
Это было бы трудно сделать если станд.:: пол возвратил интервал (или по крайней мере у Вас будет дополнительный ненужный бросок, там замедляющий вещи).
, Если пол только выполняет округление себя, не изменяя тип, можно бросить это к интервалу, если/когда Вы должны.
Другая причина состоит в том, что диапазон удваивается, намного больше, чем тот из ints. Это не может быть возможно к раунду, который все удваивает до ints.
В стандарте C ++ сказано (4.9.1):
«r-значение типа с плавающей запятой может быть преобразовано в r-значение целочисленного типа. Преобразование усекается, то есть дробная часть отбрасывается. Поведение не определено, если усеченное значение не может быть представлено в целевом типе ".
Таким образом, если вы конвертируете двойное значение в int, это число находится в диапазоне от int и необходимого округления стремится к нулю, тогда достаточно просто привести число к int:
(int) x;