Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

libGDX-2.3:Pixmap 像素圖-進階

大木頭君 2021-08-25 19:48:42 阅读数:5439 评论数:0 点赞数:0 收藏数:0

前言

本節是第二節的番外,介紹在第二節中出現過的com.badioc.gdx.graphics.pixmap類。

回顧

回顧一下第二節的介紹:

Pixmap 像素圖

我們可以通過com.badloc.gdx.graphics.Pixmap類來構建簡單的像素紋理。Pixmap常用的構造函數有:

  • Pixmap(FileHande) : 傳入一個 FileHande ,讀取圖片到 Pixmap 中
  • Pixmap(int,int,Pixmap.Format) : 傳入圖片寬高(像素單比特是整數)和 Format 對象(圖片編碼,在 Pixmap.Format 中,一般使用 Format.RGBA8888)

這時的圖片還是空白的,我們需要在圖片中繪制圖形:

設置後面繪制圖形的顏色:

//兩種都是設置黑色
pixmap.setColor(com.badloc.gdx.graphics.Color.BLACK);
pixmap.setColor(0,0,0,1);
複制代碼

繪制圖形,坐標基於圖片(左上為0,0),新圖形將覆蓋舊圖形:

pixmap.fill();  //填充整個圖片
pixmap.fillCircle(10,10,10);  //畫一個(10,10),半徑10的實心圓
pixmap.fillRectangle(30,10,10,20);  //畫一個(30,10),大小10*20的實心矩形
Pixmap.fillTriangle(0,10,5,0,10,10); //畫一個(0,10),(5,0),(10,10)(三角形三個點的坐標)的實心三角形
pixmap.drawCircle(10,10,10);  //畫一個空心圓
pixmap.draRectangle(30,10,10,20);  //畫一個空心矩形
pixmap.drawLine(0,0,100,100);  //畫從(0,0)到(100,100)的直線(1像素)
pixmap.drawPixmap(pixmap2,0,0);  //將另一個 Pixmap 繪制在圖片上(套娃 doge)
複制代碼

Pixmap 進階

回顧結束,正文開始。

下面是基於像素的方法:

//獲取像素顏色
int color=pixmap.getPixel(pixelX,pixelY);
//繪制一個像素
pixmap.drawPixel(pixelX,pixelY,Color.BLACK);
pixmap.setColor(Color.BLACK);
pixmap.drawPixel(pixelX,pixelY);
複制代碼

使用int 存儲 RGBA 顏色

那麼,Pixmap.getPixel()返回的 int 值代錶了 RGBA 顏色,這裏就要科普一下了:

RGBA 顏色是由四個八比特二進制數 錶示的,一共32比特,而 Java 中 int 類型剛好32比特,所以,使用 int 錶示 RGBA 顏色再合適不過了

libGDX 中的 Color 類中的常量是 int 類型,也是使用 int 存儲 RGBA 顏色,也就是說,可以:

if(color==Color.Black){/*...*/}
複制代碼

那麼,如何存儲/讀取 RGBA 顏色呢?很簡單:

//從 color 到 RGBA
public int[] colorToRGBA(int color){
    //alpha為最高比特
    int alpha=color>>>24;
    //其它按順序次之
    int r=( color & 0xff0000 ) >> 16 ;
    int g=( color & 0xff00 ) >> 8;
    int b= color & 0xff ;
    int colors[] =new int[4];
    //... RGBA 依次賦值給colors,這裏略
    return colors; 
}
//從 RGBA 到 color
public int RGBAtoColor(int r,int g,int b,int alpna){
    //alpha 為最高比特
    int color = (alpha<<24) | (r<<16) | (g<<8) | b;
    return color;
}
複制代碼

PixmapIO 圖片流

com.badloc.gdx.graphics.PixmapIO 類的靜態方法 提供了圖片的讀取和寫入:

//讀取文件到 pixmap
Pixmap pixmap = PixmapIO.readCIM(fileHander);
//將pixmap 寫到文件中
PixmapIO.wirteCIM(fileHander,pixmap);
PixmapIO.writePNG(fileHander,pixmap);
複制代碼

.png to .cim

我們注意到,PixmapIO 只能讀取 .cim 文件,不能讀取 .png 文件,這就很雞肋了。不過我們可以卡一下 "Bug" :

  1. Pixmap 有個構造函數可以讀取 .png 文件  

  2. PixmapIO 可以保存 .cim文件

嘿嘿,想到了吧,我們可以制作一個** .png to .cim** 的工具。

jar下載:點此,提取碼:wood

源碼下載:點此,提取碼:wood

界面如下:

libGDX2-3run.png

關鍵源碼如下:

Pixmap pixmap=new Pixmap(loadFile);
PixmapIO.writeCIM(saveFile, pixmap);
複制代碼

然鹅事實上,直接使用 pixmap.drawPixmap(new Pixmap(PNGpath)) 效果更好 :D

嘗試 :繪圖小程序

不管怎樣,我們現在都大概學會了 Pixmap 的進階使用。那麼接下來,我們將制作一個繪圖小程序,它可以更改畫筆大小和顏色,還可以保存文件

package com.libGDX.test;
import java.awt.Container;
import java.io.File;
import java.util.Date;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.PixmapIO;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
//應用主類
public class Test extends ApplicationAdapter {
    private SpriteBatch batch;
    private Pixmap pixmap;    //畫板
    private Texture texture;    //繪制載體
    private int r;    //畫筆半徑
    /*      * 保存文件的對話框。      * libGDX 本身不包含文件選擇框,      * 因此需要聯動 java swing 的 文件選擇框      */
    private JFileChooser saveDirecrotyChooser;    
    @Override
    public void create() {
        batch=new SpriteBatch();
        //創建一個500*500屏幕大小的 Pixmap 作畫板,皆畫筆
        pixmap=new Pixmap(500,500,Pixmap.Format.RGBA8888);
        //白色做畫板背景
        pixmap.setColor(Color.WHITE);
        pixmap.fill();
        //默認是黑色畫筆
        pixmap.setColor(Color.BLACK);
        //默認畫筆半徑是5,小號
        r=5;
        //初始化 texture
        texture=new Texture(pixmap);
        
        //設置輸入反饋
        Gdx.input.setInputProcessor(new InputAdapter() {
            //松開(點擊)鍵盤事件
            @Override
            public boolean keyUp(int keycode) {
                //查看是否更改屬性
                setColor(keycode);
                setSize(keycode);
                
                //如果按下 S 則保存文件
                if(keycode==Keys.S)save();
                return false;
            }
            
            //點擊和拖動時在畫板上繪制
            @Override
            public boolean touchDown(int screenX, int screenY, int pointer, int button) {
                draw(screenX,screenY);
                return false;
            }
            @Override
            public boolean touchDragged(int screenX, int screenY, int pointer) {
                draw(screenX,screenY);
                return false;
            }
        });
        //初始化文件選擇框
        saveDirecrotyChooser=new JFileChooser("");
        //設置存儲 .png 圖片
        saveDirecrotyChooser.setAcceptAllFileFilterUsed(false);
        saveDirecrotyChooser.addChoosableFileFilter(new FileNameExtensionFilter("PNG","png"));
    }
    @Override
    public void render() {
        //白色清屏
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        
        batch.begin();
        //繪制
        batch.draw(texture, 0, 0);
        
        batch.end();
    }
    
    //畫筆繪制
    private void draw(int x,int y) {
        //畫筆其實是個圓
        pixmap.fillCircle(x, y, r);
        //刷新
        texture.draw(pixmap, 0, 0);
    }
    
    //設置畫筆顏色
    private void setColor(int keycode) {
        switch(keycode) {
            case Keys.R:pixmap.setColor(Color.RED);break;    //紅色
            case Keys.G:pixmap.setColor(Color.GREEN);break;    //綠色
            case Keys.B:pixmap.setColor(Color.BLUE);break;    //藍色
            case Keys.A:pixmap.setColor(Color.BLACK);break;    //黑色
            case Keys.W:pixmap.setColor(Color.WHITE);break;    //白色,橡皮擦
        }
    }
    
    //設置畫筆大小
    private void setSize(int keycode) {
        switch(keycode) {
            case Keys.F1:r=5;break;        //小號
            case Keys.F2:r=10;break;    //中號
            case Keys.F3:r=20;break;    //大號
        }
    }
    
    //保存文件
    private void save() {
        //設置默認文件名 photo年-月-日.png
        saveDirecrotyChooser.setSelectedFile(new File("photo-"+String.format("%tF",new Date())+".png"));
        //顯示文件保存對話框
        int i =saveDirecrotyChooser.showSaveDialog(new Container());
        
        //如果按下 確定/保存
        if(i==JFileChooser.APPROVE_OPTION) {
            //以選擇路徑創建 FileHande
            FileHandle saveFile=newFileHandle(saveDirecrotyChooser.getSelectedFile().getPath());
            PixmapIO.writePNG(saveFile, pixmap);
        }
    }
    
    @Override
    public void dispose() {
        pixmap.dispose();
        texture.dispose();
        batch.dispose();
    }
}
複制代碼

運行結果:

libGDX2-3run2.png

libGDX2-3run3.png

llibGDX2-3run4.png

版权声明
本文为[大木頭君]所创,转载请带上原文链接,感谢

编程之旅,人生之路,不止于编程,还有诗和远方。
阅代码原理,看框架知识,学企业实践;
赏诗词,读日记,踏人生之路,观世界之行;

支付宝红包,每日可领