Libgdx之Pixmap

Posted zqiang_55

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Libgdx之Pixmap相关的知识,希望对你有一定的参考价值。

android刚开始流行的时候,有一些类似《吹裙子》《擦一擦》之类的小游戏非常火爆。其实他们应用的就是我们这一节所要讲的Pixmap。
Pixmap代表了内存中的图像。Pixmap有高和宽,同时也有指定的格式。Pixmap的坐标系是以左上角开始的,x轴指向右,y轴指向下。默认情况下使用混合渲染的(blending),可以使用方法 setBlending 来开启或者关闭。方法Pixmap.drawPixmap(Pixmap, int, int, int, int, int, int, int, int)将会按比例缩放或者拉伸图像。Pixmap图像存放在堆内存中(native heap memory),不再使用的时候应该调用方法dispose 来销毁防止内存泄露。
其实说白了 Pixmap 就是内存中的图像,但是我们可以对这块图像进行操作,实现一些涂抹的工作,比如实现下面图示的效果:

但是,要想Pixmap真正的在屏幕上显示出来,还需要和Texture结合,才能真正的在屏幕上画出来

下面是一个展示示例:

public class PixmapTest extends ApplicationAdapter 
    private static final String TAG = PixmapTest.class.getSimpleName();

    SpriteBatch batch;
    InputA inputA;
    Texture texture;
    Pixmap pixmap;
    FileHandle file;

    @Override
    public void create() 
        batch = new SpriteBatch();
        inputA = new InputA();
        Gdx.input.setInputProcessor(inputA);
        /**
         * RGBA8888 - This is the format we described in the earlier Primer
         * section. Each channel (R, G, B, A) is made up of a byte, or 8 bits.
         * With this format, we have four bytes per pixel. We would use this for
         * high-quality color that requires an alpha channel, for transparency.
         * This is known as "True Color". RGB888 - This is similar to the above,
         * but discards the alpha channel (i.e. the image is opaque). This is
         * useful for high-quality images that don't need an alpha channel.
         * RGBA4444 - This is similar to RGBA8888, but stores each channel in
         * only 4 bits. This leads to lower color quality, but has performance
         * and memory implications on low-end devices like Android and ios.
         * RGB565 - This stores the red channel in 5 bits, the green in 6 bits,
         * and the blue in 5 bits. We use an extra bit in the green channel
         * since the human eye can generally perceive more gradations of green.
         * This is known as "High Color", and is again mainly useful for low-end
         * or embedded devices. LuminanceAlpha - This is a grayscale image that
         * includes an alpha channel. Grayscale colors have equal red, green and
         * blue values, which we call "luminance." So a typical gray value of
         * (R=127, G=127, B=127, A=255) would be represented like so with
         * LuminanceAlpha: (L=127, A=255). Each uses 8 bits. Alpha - This is a
         * special type of image that only stores an alpha channel in 8 bits.
         * Intensity - This is another special type of image which only uses a
         * single channel, but with the alpha channel equal to the luminance.
         * For example, an Intensity color of (I=127) would be equivalent to a
         * RGBA color of (R=127, G=127, B=127, A=127).
         */
        pixmap = new Pixmap(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), Pixmap.Format.RGBA4444);

        // Fill it red
        pixmap.setColor(Color.RED);
        pixmap.fill();

        // Draw two lines forming an X
        pixmap.setColor(Color.BLACK);
        pixmap.drawLine(0, 0, pixmap.getWidth() - 1, pixmap.getHeight() - 1);
        pixmap.drawLine(0, pixmap.getHeight() - 1, pixmap.getWidth() - 1, 0);

        // Draw a circle about the middle
        pixmap.setColor(Color.YELLOW);
        pixmap.drawCircle(pixmap.getWidth() / 2, pixmap.getHeight() / 2, pixmap.getHeight() / 2 - 1);

//      pixmap = new Pixmap(Gdx.files.internal("badlogic.jpg"));
        texture = new Texture(pixmap);

        file = Gdx.files.local("bin/img/pixmap.cim");;
    

    @Override
    public void render() 
        Gdx.gl.glClearColor(0.39f, 0.58f, 0.92f, 1.0f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        batch.begin();
        batch.draw(texture, 0, 0);
        batch.end();

    

    @Override
    public void dispose() 
        batch.dispose();
        pixmap.dispose();
        texture.dispose();
    

    class InputA extends InputAdapter 
        @Override
        public boolean keyTyped(char character) 
            switch (character) 
            case 's':
                PixmapIO.writeCIM(file, pixmap);
                Gdx.app.log(TAG, "saved to " + file);
                return true;
            case 'l':
                pixmap.dispose();
                if (file.exists()) 
                    pixmap = PixmapIO.readCIM(file);
                    texture.draw(pixmap, 0, 0);
                    Gdx.app.log(TAG, "load from " + file);
                 else 
                    Gdx.app.log(TAG, file + " doesn't exit");
                
                return true;
            default:
                return false;
            
        

        @Override
        public boolean touchDragged(int screenX, int screenY, int pointer) 
            // 定义画笔的颜色
            pixmap.setColor(Color.BLUE);
            // 画笔其实是一个圆
            pixmap.fillCircle(screenX, screenY - (Gdx.graphics.getHeight() - pixmap.getHeight()), 5);
            // 将Pixmap和texture相结合
            texture.draw(pixmap, 0, 0);
            return super.touchDragged(screenX, screenY, pointer);
        
    

通过上面代码可以知道,当按键s时可以保存要画的图片,关掉程序,重新启动后,按l可以重新加载绘制的图片。 PixmapIO用来读写图片

如果感觉上面的内容还不够使用的话,可以参考链接, 这里是另外一个例子,希望能更好的帮助你理解。

以上是关于Libgdx之Pixmap的主要内容,如果未能解决你的问题,请参考以下文章

Pixmap无法按预期工作 - LibGdx

libgdx- pixmap:我能以某种方式改变线条的宽度吗?

如何在 libgdx 中正确设置 FrameBuffer 的宽度和高度?

LibGDX触摸协调混乱

线程同步那点事儿之semaphore+barrier的应用

Libgdx之监听用户输入