Java中實(shí)現(xiàn)可拖放圖片剪裁入門(mén)教程
這是一篇入門(mén)級(jí)文章,高手請(qǐng)略過(guò)。
在這篇文章中我們將學(xué)習(xí)如何用 Java 對(duì)圖像進(jìn)行剪裁并將剪裁出來(lái)的部分單獨(dú)保存到文件中。
我們將通過(guò)以下步驟來(lái)學(xué)習(xí):
1.輸入圖像,指定要處理的圖像路徑
2.允許用戶拖放要剪裁的部分
3.選擇后使用 Robot 類來(lái)確定剪裁部分的坐標(biāo)
4.剪裁所選圖像并保持
接下來(lái)我們開(kāi)始編碼部分。
Listing1: 引入的類
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
說(shuō)明:
1.Graphics 類包含繪制矩形的方法
2.我們使用 Rectangle 類作為拖拉的矩形區(qū)域以作剪裁
3.Robot 類用于捕獲屏幕截圖
4.使用鼠標(biāo)偵聽(tīng)器來(lái)獲取鼠標(biāo)的拖拉時(shí)間
5.Robot 類使用 BufferedImage 來(lái)做圖像處理
6.File 類用于打開(kāi)圖像文件
7.ImageIO 類用于將圖像寫(xiě)到 png 或者 jpg 圖像文件中
8.JFrame 用于顯示界面
現(xiàn)在我們編寫(xiě)包含 main 方法的入口類
Listing2: 入口類
public class CropImage extends JFrame implements MouseListener, MouseMotionListener
{
int drag_status=0,c1,c2,c3,c4;
public static void main(String args[])
{
new CropImage().start();
}
說(shuō)明:
1.編寫(xiě)了一個(gè)名為 CropImage 的類
2.該類擴(kuò)展了 JFrame 以實(shí)現(xiàn) frame 的所有功能
3.實(shí)現(xiàn)了不同的鼠標(biāo)事件偵聽(tīng)器以便知道用戶什么時(shí)候開(kāi)始拖動(dòng)鼠標(biāo)指針
4.drag_status 變量用于保存鼠標(biāo)開(kāi)始拖動(dòng)時(shí)的坐標(biāo)
5.我們定義了 main 方法去調(diào)用一個(gè) start 方法,這個(gè)方法將在下面定義
接下來(lái)是 start 方法
Listing 2
public void start()
{
ImagePanel im=new ImagePanel("F:\\Wallpaper\\wallpapers\\1.jpg");
add(im);
setSize(400,400);
setVisible(true);
addMouseListener(this);
addMouseMotionListener( this );
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
說(shuō)明:
1.我們定義一個(gè)名為 ImagePanel 的類,使用要處理的圖像作為參數(shù)
2.在 JFrame 中放置這個(gè)要顯示圖片的 ImagePanel,并開(kāi)始偵聽(tīng)鼠標(biāo)事件
下面我們定義用于處理鼠標(biāo)事件的方法
Listing 3: 鼠標(biāo)事件處理函數(shù)
@Override
public void mouseClicked(MouseEvent arg0) {
}
@Override
public void mouseEntered(MouseEvent arg0) {
}
@Override
public void mouseExited(MouseEvent arg0) {
}
@Override
public void mousePressed(MouseEvent arg0) {
repaint();
c1=arg0.getX();
c2=arg0.getY();
}
@Override
public void mouseReleased(MouseEvent arg0) {
repaint();
if(drag_status==1)
{
c3=arg0.getX();
c4=arg0.getY();
try
{
draggedScreen();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
@Override
public void mouseDragged(MouseEvent arg0) {
repaint();
drag_status=1;
c3=arg0.getX();
c4=arg0.getY();
}
@Override
public void mouseMoved(MouseEvent arg0) {
}
public void paint(Graphics g)
{
super.paint(g);
int w = c1 - c3;
int h = c2 - c4;
w = w * -1;
h = h * -1;
if(w<0)
w = w * -1;
g.drawRect(c1, c2, w, h);
}
說(shuō)明:
1.當(dāng)鼠標(biāo)按下時(shí)存儲(chǔ)當(dāng)前坐標(biāo)到 c1 和 c2
2.當(dāng)鼠標(biāo)按下并開(kāi)始拖動(dòng)時(shí)將拖動(dòng)狀態(tài)變量 drag_status 設(shè)置為 true
3.到鼠標(biāo)按鍵松開(kāi)時(shí)表示圖像剪裁區(qū)域已經(jīng)選擇完畢,調(diào)用 draggedscreen 方法
4.paint 方法用于拖動(dòng)時(shí)候的矩形顯示,通過(guò)當(dāng)前坐標(biāo)和初始記錄的坐標(biāo)來(lái)繪制矩形
下面是 draggedscreen 方法的代碼
Listing 4: draggedScreen 方法
public void draggedScreen()throws Exception
{
int w = c1 - c3;
int h = c2 - c4;
w = w * -1;
h = h * -1;
Robot robot = new Robot();
BufferedImage img = robot.createScreenCapture(new Rectangle(c1, c2,w,h));
File save_path=new File("screen1.jpg");
ImageIO.write(img, "JPG", save_path);
System.out.println("Cropped image saved successfully.");
}}
說(shuō)明:
1.首先計(jì)算圖像的高度和寬度
2.使用 Robot 類來(lái)對(duì)剪裁的區(qū)域進(jìn)行截圖并保持到另外一個(gè)文件 screen1.jpg
完整的代碼
Listing 5: ImagePanel.java
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
class ImagePanel extends JPanel {
private Image img;
public ImagePanel(String img) {
this(new ImageIcon(img).getImage());
}
public ImagePanel(Image img) {
this.img = img;
Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
// Dimension size = new Dimension(10,10);
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
setSize(size);
setLayout(null);
}
public void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, null);
}
}
Listing 6:CropImage.java
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class CropImage extends JFrame implements MouseListener, MouseMotionListener
{
int drag_status=0,c1,c2,c3,c4;
public static void main(String args[])
{
new CropImage().start();
}
public void start()
{
ImagePanel im=new ImagePanel("F:\\Wallpaper\\wallpapers\\1.jpg");
add(im);
setSize(400,400);
setVisible(true);
addMouseListener(this);
addMouseMotionListener( this );
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void draggedScreen()throws Exception
{
int w = c1 - c3;
int h = c2 - c4;
w = w * -1;
h = h * -1;
Robot robot = new Robot();
BufferedImage img = robot.createScreenCapture(new Rectangle(c1, c2,w,h));
File save_path=new File("screen1.jpg");
ImageIO.write(img, "JPG", save_path);
System.out.println("Cropped image saved successfully.");
}
@Override
public void mouseClicked(MouseEvent arg0) {
}
@Override
public void mouseEntered(MouseEvent arg0) {
}
@Override
public void mouseExited(MouseEvent arg0) {
}
@Override
public void mousePressed(MouseEvent arg0) {
repaint();
c1=arg0.getX();
c2=arg0.getY();
}
@Override
public void mouseReleased(MouseEvent arg0) {
repaint();
if(drag_status==1)
{
c3=arg0.getX();
c4=arg0.getY();
try
{
draggedScreen();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
@Override
public void mouseDragged(MouseEvent arg0) {
repaint();
drag_status=1;
c3=arg0.getX();
c4=arg0.getY();
}
@Override
public void mouseMoved(MouseEvent arg0) {
}
public void paint(Graphics g)
{
super.paint(g);
int w = c1 - c3;
int h = c2 - c4;
w = w * -1;
h = h * -1;
if(w<0)
w = w * -1;
g.drawRect(c1, c2, w, h);
}
}
相關(guān)文章
mybatis-plus阻止全表更新與刪除的實(shí)現(xiàn)
BlockAttackInnerInterceptor 是mybatis-plus的一個(gè)內(nèi)置攔截器,用于防止惡意的全表更新或刪除操作,本文主要介紹了mybatis-plus阻止全表更新與刪除的實(shí)現(xiàn),感興趣的可以了解一下2023-12-12
java實(shí)現(xiàn)時(shí)間與字符串之間轉(zhuǎn)換
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)時(shí)間與字符串之間轉(zhuǎn)換,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
MyBatis處理大字段或BLOB、CLOB類型數(shù)據(jù)方式
這篇文章主要介紹了MyBatis處理大字段或BLOB、CLOB類型數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-04
基于tomcat8 編寫(xiě)字符編碼Filter過(guò)濾器無(wú)效問(wèn)題的解決方法
下面小編就為大家分享一篇基于tomcat8 編寫(xiě)字符編碼Filter過(guò)濾器無(wú)效問(wèn)題的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
idea中創(chuàng)建jsp項(xiàng)目的詳細(xì)實(shí)戰(zhàn)步驟
才學(xué)javaWeb,以防自己忘記創(chuàng)建項(xiàng)目的過(guò)程,所以淺淺的記錄一下吧,下面這篇文章主要給大家介紹了關(guān)于idea中創(chuàng)建jsp項(xiàng)目的詳細(xì)步驟,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09
Java多線程編程中易混淆的3個(gè)關(guān)鍵字總結(jié)
這篇文章主要介紹了Java多線程編程中易混淆的3個(gè)關(guān)鍵字總結(jié),本文總結(jié)了、volatile、ThreadLocal、synchronized等3個(gè)關(guān)鍵字,對(duì)這幾個(gè)容易混淆概念的關(guān)鍵字分別做了講解,需要的朋友可以參考下2015-03-03
關(guān)于idea無(wú)法修改模板中jdk版本問(wèn)題
這篇文章主要介紹了關(guān)于idea無(wú)法修改模板中jdk版本問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10

