Сглаживание на иконке JButton [дубликат]

Кто-нибудь предложил что-то подобное? Просто идея для горизонтального меню ...

часть HTML


часть CSS

/* hide parent backgrounds... */
.parent-background {
  display: none; }

/* ... and show it when hover on children */
.item:hover + .parent-background {
  display: block;
  position: absolute;
  z-index: 10;
  top: 0;
  width: 100%; }

Обновлено демо и остальные кода

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

12
задан Zopesconk 31 October 2016 в 07:03
поделиться

8 ответов

Лучшая статья, которую я когда-либо читал по этой теме, - . Perils of Image.getScaledInstance () (веб-архив).

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

public BufferedImage getScaledInstance(BufferedImage img,
                                       int targetWidth,
                                       int targetHeight,
                                       Object hint,
                                       boolean higherQuality)
{
    int type = (img.getTransparency() == Transparency.OPAQUE) ?
        BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
    BufferedImage ret = (BufferedImage)img;
    int w, h;
    if (higherQuality) {
        // Use multi-step technique: start with original size, then
        // scale down in multiple passes with drawImage()
        // until the target size is reached
        w = img.getWidth();
        h = img.getHeight();
    } else {
        // Use one-step technique: scale directly from original
        // size to target size with a single drawImage() call
        w = targetWidth;
        h = targetHeight;
    }

    do {
        if (higherQuality && w > targetWidth) {
            w /= 2;
            if (w < targetWidth) {
                w = targetWidth;
            }
        }

        if (higherQuality && h > targetHeight) {
            h /= 2;
            if (h < targetHeight) {
                h = targetHeight;
            }
        }

        BufferedImage tmp = new BufferedImage(w, h, type);
        Graphics2D g2 = tmp.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
        g2.drawImage(ret, 0, 0, w, h, null);
        g2.dispose();

        ret = tmp;
    } while (w != targetWidth || h != targetHeight);

    return ret;
}
28
ответ дан Marcel Stör 20 August 2018 в 07:55
поделиться
  • 1
    да, эта статья хороша, как imgscalr, так и java-image-scaling, ссылаются на нее, но опять же результат отличается, я думаю, что фильтры, которые могут использовать масштабирование java-image-scale, имеют значение. – stivlo 31 October 2011 в 10:43
  • 2
    мои изображения png ... может ли вы отправить мне код мультистапа? пожалуйста? – JackTurky 31 October 2011 в 11:06
  • 3
    Хорошая статья, действительно помогла улучшить качество масштабированных изображений. Изменение «w / = 2» на «w / = 1,2» дает мне лучшее качество (больше циклов будет выполнено, поэтому качество лучше) – Jacob van Lingen 19 December 2014 в 10:46
  • 4
    Я попробовал предложение w / = 1.2, но обнаружил, что уменьшенные изображения размыты, особенно при гораздо меньших размерах. Я пробовал 1.5, и это не помогло, поэтому я придерживаюсь w / = 2. – MiguelMunoz 19 July 2016 в 08:16

Да, у меня были те же проблемы и они были решены, пожалуйста, прочитал мой вопрос (ответ вставлен в вопрос). Я попробовал библиотеки imgscalr и java-image-scaling и нашел второе гораздо лучшее качество. Подходите к монитору, чтобы оценить разницу между примерами миниатюр.

Несмотря на мои первоначальные мысли, изменение размера изображения кажется очень сложным, вы не хотите делать это самостоятельно. Например, я скажу java-image-scaling , чтобы использовать ResampleFilters.getLanczos3Filter() для получения лучшего результата.

В нем также рассматриваются способы сохранения JPG с качеством, превышающим стандартное значение 75, который создает плохой результат, особенно для миниатюры.

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

1
ответ дан Community 20 August 2018 в 07:55
поделиться

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

0
ответ дан cyril 20 August 2018 в 07:55
поделиться

Ни один из ответов не поможет вам получить реальное качество, которое вы желаете. Включите файл thumbailator.jar в свой проект (загрузите его здесь):

https://code.google.com/p/thumbnailator/

https://code.google.com/p/thumbnailator/wiki/Downloads?tm=2

Затем сначала загрузите изображение (как файл, без Thumbnailator - его использование - создавать большие пальцы, но вы можете создавать большие изображения с ним, конечно), и изменять его размер до любых размеров, которые вы хотите (например, с Thumbnailator 800x600). Качество будет очень хорошим. Я искал это долгое время, этот .jar помог мне достичь того, чего я хочу.

2
ответ дан DarioBB 20 August 2018 в 07:55
поделиться
  • 1
    Привет, спасибо, что поделились! Это старая должность, но я попробую и запомню будущее. Благодаря! – JackTurky 10 April 2015 в 18:14

Если ваш источник изображения является png, используйте следующие функции:

Image imgSmall = imgBig.getScaledInstance(
        targetWidth, targetHeight, Image.SCALE_SMOOTH);

Если вы хотите изменить размер jpeg или gif без лишнего качества, я создал библиотеку в 2010 году для этого: beautylib on github , который использует внутренне эту другую библиотеку: java-image-scaling . Вы можете непосредственно увидеть исходный код, чтобы найти что-то полезное: https://github.com/felipelalli/beautylib/blob/master/src/br/eti/fml/beautylib/ResizeImage.java

2
ответ дан Felipe 20 August 2018 в 07:55
поделиться

Знаю, что вопрос старый ... Я пробовал разные решения, занимаясь серфингом, затем веб, я получил лучший результат, используя getScaledInstance(), поставляя Image.SCALE_SMOOTH в качестве аргумента. На самом деле качество изображения было действительно лучше. Мой код ниже:

final int THUMB_SIDE = 140;
try {
    BufferedImage masterImage = ImageIO.read(startingImage);
    BufferedImage thumbImage = new BufferedImage(THUMB_SIDE, THUMB_SIDE, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2d = thumbImage.createGraphics();
    g2d.drawImage(masterImage.getScaledInstance(THUMB_SIDE, THUMB_SIDE, Image.SCALE_SMOOTH), 0, 0, THUMB_SIDE, THUMB_SIDE, null);
    g2d.dispose();
    String thumb_path = path.substring(0, path.indexOf(".png")) + "_thumb.png";
    ImageIO.write(thumbImage, "png", new File(thumb_path));
} catch (IOException e) {
    e.printStackTrace();
}
5
ответ дан Jens 20 August 2018 в 07:55
поделиться
  • 1
    Это рекомендуется только для «png»? – Tiny 13 July 2016 в 15:08
  • 2
    @Tiny Насколько я помню, я только тестировал его с помощью png ... – user3564042 15 July 2016 в 14:28

Следующий код дал мне высочайшее качество с сохранением пропорций. Пробовал несколько вещей и прочитал несколько статей, представленных здесь в других ответах. Потерял два дня, и в итоге я получил лучший результат с помощью простого Java-метода (попробовал также библиотеки ImageMagick и java-image-scaling):

public static boolean resizeUsingJavaAlgo(String source, File dest, int width, int height) throws IOException {
  BufferedImage sourceImage = ImageIO.read(new FileInputStream(source));
  double ratio = (double) sourceImage.getWidth()/sourceImage.getHeight();
  if (width < 1) {
    width = (int) (height * ratio + 0.4);
  } else if (height < 1) {
    height = (int) (width /ratio + 0.4);
  }

  Image scaled = sourceImage.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING);
  BufferedImage bufferedScaled = new BufferedImage(scaled.getWidth(null), scaled.getHeight(null), BufferedImage.TYPE_INT_RGB);
  Graphics2D g2d = bufferedScaled.createGraphics();
  g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
  g2d.drawImage(scaled, 0, 0, width, height, null);
  dest.createNewFile();
  writeJpeg(bufferedScaled, dest.getCanonicalPath(), 1.0f);
  return true;
}


/**
* Write a JPEG file setting the compression quality.
*
* @param image a BufferedImage to be saved
* @param destFile destination file (absolute or relative path)
* @param quality a float between 0 and 1, where 1 means uncompressed.
* @throws IOException in case of problems writing the file
*/
private static void writeJpeg(BufferedImage image, String destFile, float quality)
      throws IOException {
  ImageWriter writer = null;
  FileImageOutputStream output = null;
  try {
    writer = ImageIO.getImageWritersByFormatName("jpeg").next();
    ImageWriteParam param = writer.getDefaultWriteParam();
    param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    param.setCompressionQuality(quality);
    output = new FileImageOutputStream(new File(destFile));
    writer.setOutput(output);
    IIOImage iioImage = new IIOImage(image, null, null);
    writer.write(null, iioImage, param);
  } catch (IOException ex) {
    throw ex;
  } finally {
    if (writer != null) {
      writer.dispose();
    }
    if (output != null) {
      output.close();
    }
  }
}
8
ответ дан Mladen Adamovic 20 August 2018 в 07:55
поделиться
  • 1
    Код, отправленный @nfechner, является улучшением для вас. Если картина большая, качество будет не таким хорошим, как вы ожидали. Как написано в данной статье: «Причина такого несоответствия в качестве обусловлена ​​различными используемыми алгоритмами фильтрации. Если масштабирование более чем в два раза, алгоритмы BILINEAR и BICUBIC, как правило, теряют информацию из-за того, как пиксели выбираются из исходного изображения ». Используя многоступенчатый способ рендеринга, изображение с измененным размером будет лучше. – Jacob van Lingen 19 December 2014 в 10:53
  • 2
    Я использовал свои глаза и уменьшенные изображения до 320 пикселей, и это, по моему мнению, улучшило качество. Я понимаю, что вы говорите, однако я не был доволен результатом, полученным от алгоритма @nfechner, я тоже это пробовал ... – Mladen Adamovic 10 February 2015 в 10:59

Ответ: Удалите подсказки VALUE_INTERPOLATION_BILINEAR и VALUE_RENDERING_QUALITY.

Пример:

public static BufferedImage resizeImage(BufferedImage image, int width, int height) {

    // Temporary image

    BufferedImage tmp = image;

    // Result image

    BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

    // Graphics object

    Graphics2D graphics = (Graphics2D)result.createGraphics();

    // Add rendering hints

    graphics.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
    graphics.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);

    // Draw tmp

    graphics.drawImage(tmp, 0, 0, width, height, null);

    // Dispose of graphics object

    graphics.dispose();

    // Return image result

    return result;
}

Примечание. : По какой-то причине подсказки VALUE_INTERPOLATION_BILINEAR и VALUE_RENDERING_QUALITY размывают изменение размера изображения.

-1
ответ дан Zopesconk 20 August 2018 в 07:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: