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

别再傻傻分不清PBR和NPR了!从《原神》到《双城之战》,聊聊游戏里那些让你眼前一亮的渲染风格

本文深入解析了PBR(基于物理的渲染)与NPR(非真实感渲染)在游戏视觉风格中的应用差异,通过《原神》和《双城之战》的案例,展示了两种渲染技术如何创造出截然不同的艺术效果。从技术原理到实战案例,帮助读者理解如何根据项目需求选择合适的渲染风格。

weixin_30425949的博客 146

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

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

gitblog_00029的博客 605

别再傻傻分不清!5分钟搞懂倾斜摄影里‘地面分辨率’和‘模型精度’到底啥关系

本文深入解析倾斜摄影中‘地面分辨率’与‘模型精度’的关系,帮助读者快速理解两者的本质区别与内在关联。通过实战案例和公式计算,详细说明如何从航飞设计到精度验证全流程控制,避免常见认知误区,并针对不同应用场景提供精度需求建议。

weixin_33700350的博客 477

Java 让图片动起来

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

wu_android的博客 645

从零构建Elasticsearch MCP代理:自然语言查询背后的技术揭秘

本文深入解析如何从零构建Elasticsearch MCP代理,实现自然语言查询的技术架构与实战应用。通过MCP协议与Elasticsearch的结合,系统能够将自然语言转换为精确的DSL查询,提升非技术用户的数据查询效率。文章详细介绍了核心架构、DSL生成引擎、端到端系统搭建及生产环境最佳实践,为开发者提供全面的技术指南。

lll78的博客 877

乐企归集能力说明文档V2.0006

纳税人销售货物、提供服务开具的增值税发票及购进货物、接受服务取得的增值税发票、海关缴款书(含出口转内销证明)、代扣代缴完税凭证,可以通过本能力进行归集。纳税人可将本能力中的各类规则和接口嵌入本单位信息化系统中(如:销售、报销、财务等),实现发票自动化归集,便于纳税人完成发票入账、抵扣、退税以及代办退税等操作,有效提升涉税业务办理效率。

记录点滴 573

java的graphics2d_Java Graphics2D类的绘图方法

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

weixin_42696333的博客 1445

【Jenkins】Jenkins :首次登录直接使用 admin 账户

目录 一、使用admin账户 二、修改admin用户密码 三、管理视图 一、使用admin账户 安装时,自定义安装,选择必要的插件安装,设置Jenkins的URL为: http://本机或服务器IP:8080 然后在创建第一个管理者界面,直接选择:使用admin 二、修改admin用户密码 进入:系统管理——管理用户——选中用户——点击设置图标——修改密码: 三、...

顾三殇 —— 博客空间(软件测试) 1万+

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

Agent智能体:核心概念与架构——建立系统认知

本文摘要介绍了Agent智能体的核心概念与架构设计。主要内容包括: Agent定义与分类:阐述了Agent作为能够感知环境、决策执行的智能实体,重点分析了现代基于大语言模型(LLM)的Agent架构。 核心模块组成:详细说明了Agent的五大核心模块(感知、规划、记忆、工具和执行)及其交互流程。 UML建模展示:通过类图和序列图,清晰呈现了Agent系统的静态结构和动态执行过程。 项目结构设计:给出了模块化的代码目录结构,为实际开发提供参考框架。

lza_csdn2019的博客 634

8、音频运行时系统的架构设计

本文深入探讨了音频运行时系统的分层设计及其优势,包括逻辑层和物理层的功能划分。通过分层设计,开发者可以更轻松地管理和优化音频资源,确保其在不同平台上的高效运行。文章还介绍了平台适配与优化、错误处理与调试以及未来发展方向等内容,为开发者提供了宝贵的参考和指导。

juice的博客 461

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

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

weixin_39543647的博客 492

国科大学习资料--机器人智能控制_袁如意老师PPT后习题答案(学长精心整理)

人工神经元激活函数的作用是什么? 答:激活函数是用来加入非线性因素的,提高神经网络对模型的表达能力,解决线性模型所不能解决的问题。 人工神经网络的学习规则有哪些?各有何特征? 答:大类可以分为无监督学习算法、有监督学习算法和强化学习。其中无监督学习算法指只有输入信息,没有期望的输出信息,如Hebb学习规则,神经元连接强度的变化与两个相互连接的神经元的激活水平成正比。竞争学习法则:网络各输出单元相互竞争,最后达到只有一个最强者激活。有监督学习算法指同时提供输入信息和对应的期望输出信息,如误差学习(Delta学

无名何许人的博客 1486

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

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

wj_rdk的博客 1504

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

JAVA图形绘制

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

MeyrlNotFound的博客 1358

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

上一篇: 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、付费专栏及课程。

余额充值