Java 2D 图形变换方法

java图片旋转指定角度 package com.util; import java.awt.Graphics; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; impo 阅读详情

Graphics2D 类中的 rotate() 和 shear() 方法,它们能让你轻松实现图片的旋转和变形效果
 

一、旋转方法:rotate()

基本用法

rotate() 方法用于旋转图形或图像。它有两种主要形式:

// 形式1:围绕原点(0,0)旋转
void rotate(double theta)

// 形式2:围绕指定点(x,y)旋转
void rotate(double theta, double x, double y)
参数说明
  • theta:旋转角度(弧度值)。注意,Java 中角度通常用弧度表示,而非度数。
    • 要将度数转为弧度:Math.toRadians(角度)
    • 例如:90 度 = Math.toRadians(90) ≈ 1.57 弧度
  • x, y:旋转中心点的坐标。如果不指定,默认围绕原点 (0,0) 旋转。
  • // 围绕原点旋转45度
    g2.rotate(Math.toRadians(45));
    g2.drawImage(img, 0, 0, this);
    
    // 围绕图片中心旋转90度
    int centerX = img.getWidth(this) / 2;
    int centerY = img.getHeight(this) / 2;
    g2.rotate(Math.toRadians(90), centerX, centerY);
    g2.drawImage(img, 0, 0, this);

    二、变形(剪切)方法:shear()

    基本用法

    shear() 方法用于实现图形或图像的剪切变形,就像把图像 "斜着拉" 一样。

  • void shear(double shx, double shy)
    参数说明
  • shx:水平方向的剪切因子
    • 正值:向右倾斜(类似平行四边形向右倒)
    • 负值:向左倾斜(类似平行四边形向左倒)
  • shy:垂直方向的剪切因子
    • 正值:向下倾斜(类似平行四边形向下倒)
    • 负值:向上倾斜(类似平行四边形向上倒)
    • // 水平方向剪切(向右倾斜)
      g2.shear(0.5, 0);
      g2.drawImage(img, 0, 0, this);
      
      // 垂直方向剪切(向下倾斜)
      g2.shear(0, 0.3);
      g2.drawImage(img, 0, 0, this);
      
      // 同时水平和垂直剪切
      g2.shear(0.2, 0.2);
      g2.drawImage(img, 0, 0, this);

      三、使用技巧

      1. 角度与弧度的转换

      Java 中三角函数使用弧度,而我们习惯用度数:

    • 度数转弧度:Math.toRadians(度数)
    • 弧度转度数:Math.toDegrees(弧度)
    • 变换是累积的,多次调用会叠加效果:

      2. 多次变换的叠加效果
    • // 先旋转45度,再水平剪切
      g2.rotate(Math.toRadians(45));
      g2.shear(0.3, 0);
      g2.drawImage(img, 0, 0, this);
      3. 重置变换

      如果需要清除之前的变换,可以创建新的 Graphics2D 对象或使用 setTransform() 方法。

    • // 保存当前变换状态
      AffineTransform oldTransform = g2.getTransform();
      
      // 旋转并绘制第一张图片
      g2.rotate(Math.toRadians(45), centerX, centerY);
      g2.drawImage(img1, 50, 50, this);
      
      // 恢复变换状态("把玻璃转回原样")
      g2.setTransform(oldTransform);
      
      // 现在绘制第二张图片,它不会旋转
      g2.drawImage(img2, 200, 50, this);

    • import java.awt.Graphics;
      import java.awt.Graphics2D;
      import java.awt.Image;
      import javax.swing.*;
      
      public class TransformDemo extends JPanel {
          private Image image;
          
          public TransformDemo() {
              // 加载图片
              image = new ImageIcon("your-image-path.jpg").getImage();
          }
          
          @Override
          protected void paintComponent(Graphics g) {
              super.paintComponent(g);
              Graphics2D g2 = (Graphics2D) g;
              
              // 1. 原始图片
              g2.drawImage(image, 50, 50, 100, 100, this);
              
              // 2. 旋转45度
              g2.rotate(Math.toRadians(45), 200, 100);
              g2.drawImage(image, 150, 50, 100, 100, this);
              g2.rotate(-Math.toRadians(45), 200, 100); // 恢复旋转
              
              // 3. 水平剪切
              g2.shear(0.3, 0);
              g2.drawImage(image, 300, 50, 100, 100, this);
              g2.shear(-0.3, 0); // 恢复剪切
              
              // 4. 垂直剪切
              g2.shear(0, 0.3);
              g2.drawImage(image, 50, 200, 100, 100, this);
              g2.shear(0, -0.3); // 恢复剪切
              
              // 5. 组合变换:先旋转再剪切
              g2.rotate(Math.toRadians(30), 200, 250);
              g2.shear(0.2, 0.2);
              g2.drawImage(image, 150, 200, 100, 100, this);
              g2.shear(-0.2, -0.2); // 先恢复剪切
              g2.rotate(-Math.toRadians(30), 200, 250); // 再恢复旋转
          }
          
          public static void main(String[] args) {
              JFrame frame = new JFrame("图形变换演示");
              frame.add(new TransformDemo());
              frame.setSize(500, 400);
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.setVisible(true);
          }
      }

      ****************************************************************************************************

    • 旋转和变形的操作实际上是应用在整个 "画布" 上的,而不是单独的图片。

    • 一、形象理解

      想象你在一块透明的玻璃上画画:

    • 画布 = 玻璃
    • 图片 = 玻璃上画的图案
    •  

      当你调用 g2.rotate() 或 g2.shear() 时,相当于:

    • 旋转画布:你把整个玻璃旋转了一个角度
    • 变形画布:你把玻璃扭曲成了平行四边形
    •  

      这时,玻璃上的所有图案(图片)都会跟着一起旋转或变形!

    • 二、为什么这很重要?

      1. 旋转中心点的影响
    • 如果围绕原点 (0,0) 旋转,图片会围绕窗口左上角旋转
    • 如果指定中心点,图片会围绕该点旋转
      // 围绕原点旋转(图片会"飞出"窗口)
      g2.rotate(Math.toRadians(45));
      g2.drawImage(img, 50, 50, this);
      
      // 围绕图片中心旋转(效果更直观)
      int centerX = 50 + img.getWidth(this)/2;
      int centerY = 50 + img.getHeight(this)/2;
      g2.rotate(Math.toRadians(45), centerX, centerY);
      g2.drawImage(img, 50, 50, this);
      2. 变换的累积效果
    • 每次调用变换方法,都会影响后续所有的绘图操作
    • 就像你把玻璃转了一下后,再画的任何东西都会是倾斜的
    • // 先旋转画布
      g2.rotate(Math.toRadians(30));
      
      // 第一张图片会旋转
      g2.drawImage(img1, 50, 50, this);
      
      // 第二张图片也会旋转(即使没写rotate代码)
      g2.drawImage(img2, 200, 50, this);

      三、如何控制变换范围?

      如果你只想让特定图片旋转,而不影响其他图片,可以:

      1. 临时保存和恢复变换状态
      // 保存当前变换状态
      AffineTransform oldTransform = g2.getTransform();
      
      // 旋转并绘制第一张图片
      g2.rotate(Math.toRadians(45), centerX, centerY);
      g2.drawImage(img1, 50, 50, this);
      
      // 恢复变换状态("把玻璃转回原样")
      g2.setTransform(oldTransform);
      
      // 现在绘制第二张图片,它不会旋转
      g2.drawImage(img2, 200, 50, this);
      2. 只在特定范围内应用变换
    • // 绘制不变换的图片
      g2.drawImage(img1, 50, 50, this);
      
      // 创建新的Graphics2D对象(相当于拿一块新玻璃)
      Graphics2D g2Copy = (Graphics2D) g2.create();
      
      // 只在这个副本上应用变换
      g2Copy.rotate(Math.toRadians(45), centerX, centerY);
      g2Copy.drawImage(img2, 200, 50, this);
      
      // 释放副本("扔掉用过的玻璃")
      g2Copy.dispose();
      
      // 原始的g2不受影响,继续绘制其他内容
      g2.drawImage(img3, 350, 50, this);
      import java.awt.*;
      import java.awt.image.BufferedImage;
      import javax.swing.*;
      
      public class TransformExplanation extends JPanel {
          private BufferedImage image;
          
          public TransformExplanation() {
              // 创建一个简单的测试图片
              image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
              Graphics2D g = image.createGraphics();
              g.setColor(Color.RED);
              g.fillRect(0, 0, 100, 100);
              g.setColor(Color.WHITE);
              g.drawString("A", 45, 60);
              g.dispose();
          }
          
          @Override
          protected void paintComponent(Graphics g) {
              super.paintComponent(g);
              Graphics2D g2 = (Graphics2D) g;
              
              // 1. 绘制原始图片(没有变换)
              g2.drawImage(image, 50, 50, this);
              g2.drawString("原始图片", 50, 160);
              
              // 2. 旋转画布后绘制图片
              g2.rotate(Math.toRadians(45), 200, 100);
              g2.drawImage(image, 150, 50, this);
              g2.rotate(-Math.toRadians(45), 200, 100); // 恢复旋转
              g2.drawString("旋转后的图片", 150, 160);
              
              // 3. 变形画布后绘制图片
              g2.shear(0.3, 0);
              g2.drawImage(image, 250, 50, this);
              g2.shear(-0.3, 0); // 恢复变形
              g2.drawString("变形后的图片", 250, 160);
              
              // 4. 旋转后绘制多条线(展示整个画布被旋转)
              g2.rotate(Math.toRadians(30), 100, 250);
              g2.setColor(Color.BLUE);
              g2.drawLine(50, 200, 150, 200);
              g2.drawLine(50, 220, 150, 220);
              g2.drawLine(50, 240, 150, 240);
              g2.rotate(-Math.toRadians(30), 100, 250); // 恢复旋转
              g2.drawString("旋转后的画布", 50, 300);
          }
          
          public static void main(String[] args) {
              JFrame frame = new JFrame("变换原理演示");
              frame.add(new TransformExplanation());
              frame.setSize(500, 400);
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.setVisible(true);
          }
      }

      总结

    • 变换操作应用于画布,而不是单独的图片
    • 一旦应用变换,后续所有绘图操作都会受影响
    • 可以通过保存 / 恢复变换状态或创建副本来控制变换范围
    • 旋转中心点的选择对效果有很大影响
咱们继续学Java——高级篇 第二百零二篇:之Java 2D图形剪切与变换进阶 在Java的学习之路上,我们始终携手共进,每一个知识点的突破都是成长的见证。我写这篇博客的目的,便是与大家一同深入探索Java 2D图形处理中剪切与变换的进阶知识,助力大家在图形编程领域取得更大的进步。今天,我们将详细解读Java 2D图形中的剪切操作以及变换操作的更多细节,相信这会让你对图形处理有更深刻的理解和更熟练的运用。 阅读详情

相关推荐

52、Java 2D 图形编程:路径、区域、笔触、填充与坐标变换全解析

本文深入解析了Java 2D图形编程中的核心概念与技术,包括路径绘制、区域操作、笔触设置、填充样式以及坐标变换。通过丰富的代码示例,详细介绍了如何使用Path2D类创建复杂路径,如何通过区域操作组合图形,如何设置不同的笔触样式和填充效果,以及如何应用坐标变换实现图形的缩放、旋转和平移。最后,文章总结了Java 2D图形编程的基本流程,并提供了实践建议,帮助开发者灵活运用这些技术创建出美观且功能强大的图形界面。

ujm56789012的博客 95

Open CV 图像处理基础:(六)在Java中使用 Open CV进行图片翻转和图片旋转

在Java中使用OpenCV进行图片翻转和旋转是一种基本的图像处理技术,广泛应用于计算机视觉、图像编辑和人工智能领域。OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库,它提供了许多常见的图像处理和分析功能,旨在为实时的图像处理提供高效能的解决方案。

无间行者 2377

12、Java 2D 图形处理与图像操作全解析

本文全面解析了 Java 2D 中的图形处理与图像操作功能,涵盖了字形轮廓处理、缓冲图像的创建与操作、图像加载与处理、仿射变换等内容。通过示例代码详细介绍了如何使用 `BufferedImage`、`Graphics2D` 和 `AffineTransform` 等类进行图像处理和变换操作,并提供了性能优化建议和学习资源推荐,适合开发者深入掌握 Java 2D 图形编程的核心技术与应用。

water的专栏 74

【JAVA】Graphics2D实现图片的裁剪、旋转、翻转

2、将原图中的点(dataX,dataY),点(dataX+cropWidth,dataY+cropHeight)形成的矩形, drawImage到区域A中。1、有一块长200宽100的画布,在画布的点(dx1,dy1),点(dx2,dy2)形成的矩形区域A。指以图片中心点(125,62.5)也就是图片中心,顺时针旋转5度。指以坐标点(0,0)也就是左上角,顺时针旋转5度。以一张250x125的图片为例。

想和派大星一样 1513

51、Java 2D API 高级绘图指南

本文深入介绍了 Java 2D API 的核心功能,包括渲染管道的工作流程、各种形状类的使用、区域操作、笔触和填充的设置、坐标变换、裁剪、透明度与合成规则以及渲染提示的优化策略。通过丰富的代码示例,展示了如何利用 Java 2D API 创建高质量、复杂的图形效果,适用于需要精细控制图形绘制的 Java 应用程序开发。

ujm56789012的博客 81

64、Java 2D 绘图入门:基础形状绘制与填充技巧

本文介绍了使用 Java 2D 进行基础绘图的技巧,包括获取图形上下文、绘制和填充基本形状(如直线、矩形、椭圆、弧等)、设置颜色与透明度、文本绘制、形状变换(旋转、缩放、平移)等内容。通过示例代码,帮助开发者快速掌握 Java 2D 绘图的基本技能,并为进一步探索高级功能打下基础。

j7k8l的博客 76

Java:实现旋转图形(附带源码)

Java:实现旋转图形(附带源码)

欢迎来到我的博客!这里是一个专注于计算机技术的分享平台,涵盖编程开发、算法研究、系统架构、软件工程等多个领域。无论你是初学者还是资深开发者,都能在这里找到有价值的内容。 709

Java 2D图形库实战:从基础绘图到交互式图形应用

Java 2D图形库是Java平台中用于实现高质量二维图形绘制的核心API,它构建在AWT(Abstract Window Toolkit)基础之上,提供了丰富的绘图功能,包括形状绘制、颜色填充、文本渲染以及图像处理等。该库不仅广泛应用于Swing图形界面开发中,还被用于游戏开发、数据可视化、图表绘制等需要图形支持的场景。Java 2D API的核心优势在于其面向对象的设计理念与高度可扩展性。通过Graphics2D类、Shape接口、Paint与Stroke。

weixin_32869687的博客 1239

图片的旋转、翻转、放大和缩小

图片的旋转、翻转、放大和缩小 实际上是重写paint(Graphics g)方法 drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) 放缩图片只需要改变几个int类型的参数即可 类Graphics2D的方法rotate(double theta, double x, doubl...

kinganpo的博客 800

图形变换与透明度组合:深入理解Java 2D API

本文深入探讨了Java 2D API中的图形变换技术,包括旋转、缩放、剪切和位移操作,以及如何使用剪切技术限制绘图区域。此外,文章详细解释了透明度和图形组合规则,探讨了Porter-Duff组合原则及其在Java 2D中的实现,包括如何通过AlphaComposite类应用不同的组合规则。

weixin_42577243的博客 330

九齐NY8B062F单片机:12位ADC与4路PWM在智能家居控制中的实战应用

本文详细介绍了九齐NY8B062F单片机在智能家居控制中的实战应用,重点解析其12位ADC高精度传感器数据采集和4路PWM精准驱动技术。通过实际案例展示如何利用该单片机实现温湿度监测、灯光调节及电机控制,并分享低功耗设计与抗干扰方案,为低成本高可靠性的智能家居设备开发提供完整解决方案。

rnn9storyteller的博客 730

JOML与Java 2D/JavaFX:2D图形变换的高效实现方案

在Java图形编程领域,**JOML**(Java OpenGL Math Library)为2D图形变换提供了高效、专业的数学计算支持。这款强大的Java数学库虽然最初为OpenGL渲染设计,但其卓越的矩阵和向量运算能力使其成为Java 2D和JavaFX应用中2D图形变换的完美解决方案。无论您是在开发游戏、数据可视化工具还是图形编辑器,JOML都能显著提升您的2D图形处理性能。🎯 ## ?

gitblog_00029的博客 605

开源网格生成利器Gmsh:从入门到二次开发实战指南

本文详细介绍了开源网格生成工具Gmsh,从基础概念、安装配置到核心功能实战,提供了全面的入门指南。重点阐述了其强大的二次开发能力,通过Python API实现参数化建模、边界层网格生成以及与FEniCS、OpenFOAM等求解器的集成,为有限元分析和计算流体力学仿真提供灵活高效的自动化网格划分解决方案。

weixin_29066781的博客 434

Java 让图片动起来

是 Java 2D 图形 API 中的一个变换方法,它可以让你对绘制的内容进行旋转。类,是 Java Swing 和 AWT 中用于高级绘图的工具。

wu_android的博客 645

手把手教你用OpenCV+Python实现HALCON级模板匹配(附工业案例代码)

本文详细介绍了如何利用开源计算机视觉库OpenCV和Python,构建媲美HALCON商业软件的工业级模板匹配解决方案。通过分析工业检测的核心挑战,文章提供了从模板预处理、多策略融合匹配到应对尺度与旋转的完整代码实现,并附有连接器引脚检测的实战案例,为工业自动化场景下的高精度视觉检测提供了低成本、高可控性的技术路径。

e3f4g5的博客 283

LeGO-LOAM运行kitti数据集

文章目录1. kitti-lego-loam2. 改动3. 实验结果4. evo轨迹测评 1. kitti-lego-loam 链接:kitti-lego-loam kitti-lego-loam提供了将kitti序列转化成rosbag的代码,在kittibag中. 需要注意下数据文件的存放顺序,以00序列为例: datafolder          |____results          &

Zlp19970106的博客 8704

java的graphics2d_Java Graphics2D类的绘图方法

Java Graphics2D类的绘图方法Java语言在Graphics类提供绘制基本的几何图形的基础上,扩展Graphics类提供一个Graphics2D类,它拥用强大的二维图形处理能力,提供、坐标转换、颜色管理以及文字布局等的控制。绘图属性Graphics2D定义了几种方法,用于添加或改变图形的状态属性。可以通过设定和修改状态属性,指定画笔宽度和画笔的连接方式;设定平移、旋转、缩放或修剪变换图...

weixin_42696333的博客 1445

深入解析Incapsula reese84的生成机制与绕过策略

本文深入解析了Incapsula reese84的生成机制与绕过策略。reese84是一种基于客户端JavaScript挑战的Web安全防护,通过动态算法收集浏览器指纹并生成令牌Cookie。文章详细拆解了其两步验证流程,并提供了使用无头浏览器、逆向JS模拟请求以及Token维护等实战绕过方法,帮助开发者和安全研究人员应对自动化访问拦截。

weixin_29256771的博客 443

201711671202《Java程序设计》第十四章学习总结

教材学习内容总结 1. 当程序运行时,Java运行环境会用Graphics2D(Graphics的一个子类)将参数g实例化,对象g就可以在重写paint方法的组件上绘制图形、图像等 2. 直线:使用java.awt.geom包中的Line2D的静态内部类Double new Line2D.Double(double x1,double y1,double x2,double y2); ...

M_Mango的博客 285

低功耗设计-Power Switch

power gating与power switch cell

m0_61544122的博客 1万+

华为OD面试手撕真题 - 最大数

华为OD面试手撕真题 最大的数 提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解

qq_45776114的博客 340

java斜椭圆_JAVA 任意椭圆方向画法

展开全部使用32313133353236313431303231363533e4b893e5b19e31333332636266AffineTransform把Ellipse2D旋转一下就可以了。importjava.awt.image.BufferedImage;importjava.awt.geom.AffineTransform;importjava.awt.geom.Ellip...

weixin_39543647的博客 492

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

咱们继续学Java——高级篇 第二百二十篇:之Java 2D图形打印之多页文档布局与打印预览优化

在Java学习的征程中,我们持续探索前行,每一次对知识的深入钻研都是提升能力的关键。我撰写这篇博客的目的,便是与大家一同深入学习Java 2D图形打印中多页文档布局的计算方法以及打印预览功能的优化技巧,助力大家在图形编程领域掌握更高级的打印技术。今天,我们将详细解读多页文档布局计算的思路、打印预览对话框的优化要点,并结合实际代码示例加深理解,相信这会让你的图形打印应用在多页文档处理和用户体验方面更上一层楼。

wj_rdk的博客 1504

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

JAVA图形绘制

在Java的图形绘制中,坐标系统是一个核心概念。它确定了屏幕上的每个点的位置,使得图形元素(如文本、形状等)可以准确地绘制在指定位置。

MeyrlNotFound的博客 1358

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

上一篇: java (int)Math.random()*100 运算优先级
下一篇: java UDP 模板
wu_android
博客等级 码龄10年 94粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值