Управление изображениями

A

alik86

Наконец-то дошли руки, сделал, под размеры всё отлично подгоняет, но вот потеря качества видна даже невооружённым глазом -- как побороть?
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 951
602
BIT
422
у любых преобразований есть алгоритмы...
для ресайза они бывают разные, притом - надо учитывать качество выходного жепега (его могут ставить, например, в 90, для кач-ва надо - 100)

Добавлено: исходные коды даются для того, чтобы их читали, а не просто юзали :)
/**
* Writes the current JpgImage object to a file, with a quality
* of 0.75
*
* @param fileName the name of the file to write the image to
* (if the file already exists, it will be
* overwritten)
* @exception IOException if there is an error writing to the file
*/
public void sendToFile (String fileName) throws IOException
{
sendToFile(fileName, 0.75f);
}
 
A

alik86

Ну дык я смотрел.
public void sendToFile (String fileName, float quality) throws IOException
{
if (quality < 0) quality = 0f;
if (quality > 1) quality = 1f;
}
Тут я увидел, что 1f - это наилучшее качество, но оно какое-то потерянное... :)
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 951
602
BIT
422
потерянное оно вследствии null, в коде:<!--shcode--><pre><code class='java'>AffineTransformOp op = new AffineTransformOp
(AffineTransform.getScaleInstance(scale, scale), null);[/CODE]
читаем
а надо юзать
и инициализировать на качество и преобразование делать, например, бикубическое
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 951
602
BIT
422
дефолтные настройки афинных преобразование - скорость, а не качество
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 951
602
BIT
422
да.. , я не знаю как сейчас (с бикубической фльтрацией) в жвм, и тем паче в ИБМ реализации, но раньше он не была реализована (несмотря на присут. константы)
вот какой-то корявый перевод, но там есть код
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 951
602
BIT
422
читать отсюдова
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 951
602
BIT
422
т.е. надо пробовать типа
<!--shcode--><pre><code class='java'>AffineTransformOp op = new AffineTransformOp
(AffineTransform.getScaleInstance(scale, scale), new RenderingHints(KEY_INTERPOLATION,VALUE_INTERPOLATION_BICUBIC));[/CODE]на крайняк - получите билинейную фильтрацию, что луча чем VALUE_INTERPOLATION_NEAREST_NEIGHBOR :)
 
A

alik86

Уже перепробовал кажется все комбинации. Даже попробовал
AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(scale, scale), AffineTransformOp.TYPE_BICUBIC);

Всё равно качество получается либо такое же как было в исходном варианте (см. рис. "Вариант 1") либо как на рисунке "Вариант 2"

Рисунки:
Исходный: 666______.jpg
Вариант 1: 666_______2.jpg
Вариант 2: 666_______3.jpg

P.S. А я хоть правильно задаю параметры для RenderingHints (в плане синтаксиса)?
Код:
AffineTransformOp op = new AffineTransformOp(
AffineTransform.getScaleInstance(scale, scale),
new	RenderingHints(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC)
);
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 951
602
BIT
422
ну на самом деле, в коде не хватает корректной колормодели :trash:...
почему она не создаётся для всех фильтров, окромя "ближайшего соседа" я не скажу (не знаю)

<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">кусочек, кот. отработает прально</div></div><div class="sp-body"><div class="sp-content"><!--shcode--><pre><code class='java'> public static void sendToFile(String fileName, float quality)
throws IOException {
if (quality < 0)
quality = 0f;
if (quality > 1)
quality = 1f;

FileOutputStream out = new FileOutputStream(fileName);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(dest);
param.setQuality(quality, false);
encoder.encode(dest, param);
out.close();
}

public static void main(String args[]) throws IOException {

if (args.length == 0) {

System.err.println(

"Provide image name on command line");

System.exit(-1);

}
String fileName = args[0];
// Image image = ImageIO.read(new File(fileName));
// bi = toBufferedImage(image);
FileInputStream fis = new FileInputStream(fileName);
JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(fis);
bi = decoder.decodeAsBufferedImage();
AffineTransform tx = AffineTransform.getScaleInstance(0.5, 0.5);
// AffineTransform tx = new AffineTransform();
// tx.scale(0.5d, 0.5d);
AffineTransformOp op = new AffineTransformOp(tx,
AffineTransformOp.TYPE_BICUBIC);
dest = op.createCompatibleDestImage(bi, bi
.getColorModel());

// Filter the image and save the filtered image in the
// destination object.
op.filter(bi, dest);

// Return a reference to the destination object.
sendToFile(fileName.replaceFirst("\\.", "new."), 1f);
}[/CODE]
Добавлено: разумеется часть main д.б. ф-цией скэла (мне лениво было код делить)
и dest - это BufferedImage (я его в выделил спесуально, отдельно)
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 951
602
BIT
422
и ещё отмечу - большого кач-ва, при уменьшении в 10 раз, ждать не надо...
эти алгоритмы не спасут
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 951
602
BIT
422
вот ещё на пробу, но там не присут. афинные преобразования :trash:
есть здесь:
и тут:
тест на основе ниже
отличие заметно (для типов интерполяции)
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Код</div></div><div class="sp-body"><div class="sp-content"><!--shcode--><pre><code class='java'>import java.awt.*;
import java.awt.image.*;
import java.io.*;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class ThumbnailGenerator {
public ThumbnailGenerator() {
}

public static void transform(String originalFile, String thumbnailFile,
int thumbWidth, int thumbHeight, float quality) throws Exception {
Image image = javax.imageio.ImageIO.read(new File(originalFile));

double thumbRatio = (double) thumbWidth / (double) thumbHeight;
int imageWidth = image.getWidth(null);
int imageHeight = image.getHeight(null);
double imageRatio = (double) imageWidth / (double) imageHeight;
if (thumbRatio < imageRatio) {
thumbHeight = (int) (thumbWidth / imageRatio);
} else {
thumbWidth = (int) (thumbHeight * imageRatio);
}

if (imageWidth < thumbWidth && imageHeight < thumbHeight) {
thumbWidth = imageWidth;
thumbHeight = imageHeight;
} else if (imageWidth < thumbWidth)
thumbWidth = imageWidth;
else if (imageHeight < thumbHeight)
thumbHeight = imageHeight;

BufferedImage thumbImage = new BufferedImage(thumbWidth, thumbHeight,
BufferedImage.TYPE_INT_RGB);
Graphics2D graphics2D = thumbImage.createGraphics();
graphics2D.setBackground(Color.WHITE);
graphics2D.setPaint(Color.WHITE);
graphics2D.fillRect(0, 0, thumbWidth, thumbHeight);
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
//RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
graphics2D.drawImage(image, 0, 0, thumbWidth, thumbHeight, null);

// javax.imageio.ImageIO.write(thumbImage, "JPG", new
// File(thumbnailFile));
FileOutputStream out = new FileOutputStream(thumbnailFile);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(thumbImage);
param.setQuality(quality, false);
encoder.encode(thumbImage, param);
out.close();
}

public static void main(String args[]) throws IOException {

if (args.length == 0) {

System.err.println(

"Provide image name on command line");

System.exit(-1);

}
String fileName = args[0];
try {
transform(fileName, fileName.replaceFirst("\\.", "_new."), 300,
300, 1f);
} catch (Exception e) {
e.printStackTrace();
}
}

}[/CODE]
 

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
Всем привет!
Необходимо обрабатывать картинки. Минимум необходимо определять размер изображения - максимум - изменять размер.
Нашел вот этот Но проблема с ImageIO.
Класс не найден. Уже устал гуглить и искать где это можно взять :(
 

Kmet

Well-known member
25.05.2006
904
8
BIT
0
его не надо нигде брать, этот класс должен идти вместе jse.
приведи полный стэктрейс и попробуй явно положить rt.jar на classpath
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 951
602
BIT
422
если нотусня ниже 7-ки - могут быть проблемы (ЕМНИП его там ещё не было)
 

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
его не надо нигде брать, этот класс должен идти вместе jse.
приведи полный стэктрейс и попробуй явно положить rt.jar на classpath
Хм... действительно... такой jar в директории lib присутствует... тогда почему получаю ошибку на класс?


Agent error: java.lang.NoClassDefFoundError: javax/imageio/ImageIO
 

Kmet

Well-known member
25.05.2006
904
8
BIT
0
. действительно... такой jar в директории lib присутствует... тогда почему получаю ошибку на класс?

а если заглянуть в сам джарник? в нем класс есть?

Agent error: java.lang.NoClassDefFoundError: javax/imageio/ImageIO
Нужен полный стектрейс.
NoClassDefFoundError достаточно коварное исключение. оно не обязательное означает, что класса нет на класспасе.
Оно также бросается, если не получается инициализировать класс. Например у класса есть какая либо статическая инициализации и она падает при выполнение.


ImageIO не едиственный способ работать с изображениями
 

Kmet

Well-known member
25.05.2006
904
8
BIT
0
я не знаю нюансов разрабоки под лотус,
но думаю можно обернуть метод, который использует ImageIO, в try-catch и просто записать стектрейс в лог или в файл

или подключится дебагером и поставить брекпоинт на исключение
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!