Я сделал это около 15 лет назад, используя Swing и javax.image
, и единственное жизнеспособное решение состояло в том, чтобы применить различные уровни качества к кодировщику JPG, чтобы найти наилучшую настройку качества, для которой изображение было все еще меньше, чем запрошенный максимальный размер. Код работал примерно так (код, синтезированный из реального кода, никогда не тестировался в этой версии ...):
/** Create JPG version of some image with given JPG quality setting (0..1), helper method */
private byte[] createResultBytes(BufferedImage losslessimage,float lossyquality) {
Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("JPG");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (iter.hasNext()) {
ImageWriter writer = iter.next();
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(lossyquality);
MemoryCacheImageOutputStream mcios = new MemoryCacheImageOutputStream(baos);
writer.setOutput(mcios);
// workaround for alpha-channel problems with lossy images: Seems to be non-functional for some pictures, anyway.
BufferedImage img2=new BufferedImage(losslessimage.getWidth(),losslessimage.getHeight(),BufferedImage.TYPE_INT_RGB);
Graphics g=img2.getGraphics();
g.drawImage(new ImageIcon(losslessimage).getImage(),0,0,null);
g.dispose();
IIOImage iioimg = new IIOImage(img2, null, null);
try {
writer.write(null, iioimg, iwp);
mcios.close();
}
catch (IOException ioe) {}
}
return baos.toByteArray();
}
/** Create JPG version of some image with best JPG quality where the file size is still not larger than maxsize. */
public byte[] getLossyImage(BufferedImage losslessimage,int maxsize,float maxquality) {
byte[] resultbytes=createResultBytes(losslessimage,maxquality);
if (resultbytes.length>size) {
int minsize=(int)(size*.9f);
float newq=maxquality/2f;
resultbytes=createResultBytes(losslessimage,newq);
float qdiff=newq/2f;
while ((resultbytes.length<minsize || resultbytes.length>size) && diff>.02f) {
newq+=(resultbytes.length<minsize?qdiff:-qdiff);
resultbytes=createResultBytes(losslessimage,newq);
qdiff=qdiff/2f;
}
}
return resultbytes;
}
Обратите внимание, что я изменил размер файла только с помощью настройки качества JPG, а не с помощью автоматического изменения размер изображения. Если вы хотите пойти по этому пути, вы должны сначала применить эти изменения размера.
Отправленный запрос эквивалентен
select c from Customer c inner join c.customerOrders o where o.cost > 1000
который просто возвращает всех клиентов, которые имеют по крайней мере один порядок со стоимостью, больше, чем 1 000.
Я предложил бы обратному соединению и избранным заказам - это - семантически то же, но структурно отличающийся от Вашего желаемого результата хотя:
select o from CustomerOrder o where o.cost > 1000
Теперь, Будьте в спящем режиме, имеет non-JPA функцию под названием Фильтр, который должен выполнить точно, что Вы ищете - посмотрите здесь: http://www.hibernate.org/hib_docs/reference/en/html/filters.html