Как обрезать изображение на Java?

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

Решение, которое я нашел наиболее полезным для обрезки буферизованного изображения, использует getSubImage (x, y, w, h);

Моя процедура подметания выглядела так:

private BufferedImage cropImage(BufferedImage src, Rectangle rect) { BufferedImage dest = src.getSubimage(0, 0, rect.width, rect.height); return dest; } 

Есть две потенциально серьезные проблемы с ведущим ответом на этот вопрос. Во-первых, согласно документам:

public BufferedImage getSubimage (int x, int y, int w, int h)

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

По сути, это означает, что результат getSubimage действует как указатель, который указывает на подраздел исходного изображения.

Почему это важно? Ну, если вы планируете редактировать субимость по какой-либо причине, редактирование также произойдет с исходным изображением. Например, я столкнулся с этой проблемой, когда использовал небольшое изображение в отдельном окне, чтобы увеличить исходное изображение. (вроде как увеличительное стекло). Я позволил инвертировать цвета, чтобы увидеть некоторые детали более легко, но область, которая была «увеличена», также была перевернута в исходном изображении! Таким образом, была небольшая часть исходного изображения с инвертированными цветами, а остальная часть оставалась нормальной. Во многих случаях это не имеет значения, но если вы хотите отредактировать изображение или хотите просто получить копию обрезанного раздела, вам может потребоваться рассмотреть метод.

Это подводит нас к второй проблеме. К счастью, это не такая большая проблема, как первая. getSubImage использует тот же массив данных, что и исходное изображение. Это означает, что все исходное изображение все еще сохраняется в памяти. Предполагая, что с помощью «обрезания» изображения на самом деле требуется меньшее изображение, вам нужно будет перерисовать его как новое изображение, а не просто получить его.

Попробуй это:

 BufferedImage img = image.getSubimage(startX, startY, endX, endY); //fill in the corners of the desired crop location here BufferedImage copyOfImage = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB); Graphics g = copyOfImage.createGraphics(); g.drawImage(img, 0, 0, null); return copyOfImage; //or use it however you want 

Этот метод даст вам обрезанное изображение, которое вы ищете самостоятельно, без ссылки на исходное изображение. Это сохранит целостность исходного изображения, а также сохранит накладные расходы памяти для хранения большего изображения. (Если вы выгрузите исходное изображение позже)

Это метод, который будет работать:

 import java.awt.image.BufferedImage; import java.awt.Rectangle; import java.awt.Color; import java.awt.Graphics; public BufferedImage crop(BufferedImage src, Rectangle rect) { BufferedImage dest = new BufferedImage(rect.getWidth(), rect.getHeight(), BufferedImage.TYPE_ARGB_PRE); Graphics g = dest.getGraphics(); g.drawImage(src, 0, 0, rect.getWidth(), rect.getHeight(), rect.getX(), rect.getY(), rect.getX() + rect.getWidth(), rect.getY() + rect.getHeight(), null); g.dispose(); return dest; } 

Конечно, вы должны создать свой собственный JComponent:

 import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.image.BufferedImage; import java.awt.Rectangle; import java.awt.Graphics; import javax.swing.JComponent; public class JImageCropComponent extends JComponent implements MouseListener, MouseMotionListener { private BufferedImage img; private int x1, y1, x2, y2; public JImageCropComponent(BufferedImage img) { this.img = img; this.addMouseListener(this); this.addMouseMotionListener(this); } public void setImage(BufferedImage img) { this.img = img; } public BufferedImage getImage() { return this; } @Override public void paintComponent(Graphics g) { g.drawImage(img, 0, 0, this); if (cropping) { // Paint the area we are going to crop. g.setColor(Color.RED); g.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.max(x1, x2), Math.max(y1, y2)); } } @Override public void mousePressed(MouseEvent evt) { this.x1 = evt.getX(); this.y1 = evt.getY(); } @Override public void mouseReleased(MouseEvent evt) { this.cropping = false; // Now we crop the image; // This is the method a wrote in the other snipped BufferedImage cropped = crop(new Rectangle(Math.min(x1, x2), Math.min(y1, y2), Math.max(x1, x2), Math.max(y1, y2)); // Now you have the cropped image; // You have to choose what you want to do with it this.img = cropped; } @Override public void mouseDragged(MouseEvent evt) { cropping = true; this.x2 = evt.getX(); this.y2 = evt.getY(); } //TODO: Implement the other unused methods from Mouse(Motion)Listener } 

Я не проверял. Возможно, есть некоторые ошибки (я не уверен во всем импорте).

Вы можете поместить метод crop(img, rect) в этом classе. Надеюсь это поможет.

 File fileToWrite = new File(filePath, "url"); BufferedImage bufferedImage = cropImage(fileToWrite, x, y, w, h); private BufferedImage cropImage(File filePath, int x, int y, int w, int h){ try { BufferedImage originalImgage = ImageIO.read(filePath); BufferedImage subImgage = originalImgage.getSubimage(x, y, w, h); return subImgage; } catch (IOException e) { e.printStackTrace(); return null; } } 

На этот вопрос недостаточно информации для ответа. Общее решение (в зависимости от вашей инфраструктуры графического интерфейса): добавьте обработчик события мыши, который будет захватывать клики и движения мыши. Это даст вам ваши (x, y) координаты. Затем используйте эти координаты, чтобы обрезать изображение.

Вам нужно прочитать о Java Image API и API, относящемся к мыши, возможно, где-то под java.awt.event package .

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

Затем оттуда вы попытаетесь реализовать интерфейс прослушивания мыши и другие связанные интерфейсы. Может быть, вы будете привязаны к методу mouseDragged

Для mousedragged действия вы получите координату формы прямоугольника с помощью перетаскивания …

Затем из этих координат вы получите субимаг из изображения, которое у вас есть, и вы перерисовываете его заново ….

А затем покажите обрезанное изображение … Я не знаю, будет ли это работать, просто продукт моего воображения … просто мысль!

Я приводил этот пример, потому что это действительно работает для моего прецедента.

Для метода, приведенного ниже, BoundingBox – это субимаг, который вы пытаетесь обрезать.

 private BufferedImage cropImage(BufferedImage image, BoundingBox box) { Rectangle goal = new Rectangle(Math.round(box.getLeft()* image.getWidth()),Math.round(box.getTop()* image.getHeight()),Math.round(box.getWidth() * image.getWidth()), Math.round(box.getHeight() * image.getHeight())); Rectangle clip = goal.intersection(new Rectangle(image.getWidth(), image.getHeight())); BufferedImage clippedImg = image.getSubimage(clip.x, clip.y , clip.width, clip.height); return clippedImg; } 
  • Как разбить строку java на обратную косую черту
  • Консоль Netbeans не отображает символы юникода Bangla
  • : app: dexDebug ExecException завершен с ненулевым значением выхода 2
  • Рассчитать количество будних дней между двумя датами в Java
  • Расширение от двух classов
  • Записывать телефонные звонки на Android-телефоне?
  • Странное поведение java с приведениями к примитивным типам
  • Что вы не можете сделать на VM Dalvik (виртуальная машина Android), которую вы можете использовать в Sun VM?
  • Как hash строку в Android?
  • Электронная почта с внутреннего хранилища
  • Android: что выбрать для значений кода запроса?
  • Interesting Posts

    Как найти ярлык «Цель рекламного объявления»?

    Почему java.util.Observable не абстрактный class?

    Список или IList

    Прокси-сервер с угловым CLI для бэкэнд не работает

    Есть ли способ для нескольких процессов совместно использовать прослушивающий сокет?

    Как скрыть панель инструментов Windows 7 и панель свойств?

    Ошибка: не удалось подключиться к идентификатору процесса 0

    D-Link DIR-600M – Настройка правил QoS для ограничения полосы пропускания для данного IP-адреса

    Изменение цвета по умолчанию Firefox при открытии ссылок на новой вкладке

    Последствия предупреждения Windows Genuine Advantage?

    Как я могу заставить Linux правильно интерпретировать клавиатурные символы?

    Можно ли эллировать nptptr в gcc?

    Курсор и выбор невидимы, когда фокус теряется

    Gson и десериализация массива объектов с массивами в нем

    У моей материнской платы есть 2 отсека для бара. Почему CPU-Z и Speccy показывают, что у меня есть 4 слота?

    Давайте будем гением компьютера.