简体   繁体   中英

libGDX set color in sprite to transparent

I'm drawing sprites, from a spritesheet, to the screen. The sprites have a black background. I would like the black, and only black, to be rendered as transparent, if it's possible. So, say I have a red background. Then I have a sprite that has a blue circle with a black background. When I draw it to the screen, I want only the blue circle (and obviously the red background) to be visible. Here is the code for my current project. Help greatly appreciated!

   public void render(float delta) {
            Gdx.gl.glClearColor(1f, 1f, 1f, 1f);
            Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

            batch.setProjectionMatrix(camera.combined);
            batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
            batch.enableBlending();

            camera.update();
            generalUpdate();

            batch.begin();
            // Rendering Code
            Assets.sprite_moon.draw(batch);

            if (Assets.accelerated) {
                Assets.sprite_flame.draw(batch);
            }
            Assets.sprite_rocket.draw(batch);

            Assets.sprite_blue.draw(batch);
            // End render code
            batch.end();
            batch.disableBlending();
        }

You're looking for "chroma key" or "color key" support (and you want black to be your "chroma color"). In general, this isn't something supported by libgdx. See Removing a Sprites Color Key libGDX

However, most tools (and Libgdx) support an "alpha channel" which is a way of specifying the transparency of any pixel, independently of its color. You should be able to set the transparency when generating the image, or even when packing the image into a spritesheet. Or you can build a pre-processing pass on the images yourself. See How do you tell libgdx to use a specific color for transparency?

If you really want to go the chroma key approach, you can try using a custom shader, but I would avoid that approach unless you've got a really strong reason to play with shaders.

I know this is old but for precedence sake if nobody wants to download GIMP, I used this free website to make my sprites a transparent png:

http://www.online-image-editor.com/

I wrote the following script in python3 to replace a bunch of images with color key transparency with PNGs with an alpha channel. Feel free to use it, call it like: process_image("a.bmp", "a.png")

It requires scipy and numpy, which you can install with pip3.

 #!/usr/bin/env python3

 from scipy import misc
 import numpy as np

 def process_image(filepath, outfile):
     image = misc.imread(filepath)
     if image.shape[2] == 3:
         alpha = np.expand_dims(np.full(image.shape[:2], 255), axis=2)
         image = np.append(image, alpha, axis=2)

     width, height = image.shape[1], image.shape[0]
     color_key = image[0,0,:3]

     for x in range(width):
         for y in range(height):
             pixel = image[y,x,:3]
             if np.array_equal(pixel, color_key):
                 image[y,x,3] = 0
     misc.imsave(outfile, image)

Here's some code I'm using to make a color transparent. In this case I have a series of keyframes from a Blender render output, which use full-green as a colorkey ie. green screen.

import pygame

OUTPUT_FN = 'spritesheet.png'
SPRITE_SIZE = 256
COLUMNS = 4
ROWS = 4
TRANSP_COLOR = (0,255,0)

screen_size = ((SPRITE_SIZE * COLUMNS, SPRITE_SIZE * COLUMNS))
screen = pygame.display.set_mode(screen_size)

x, y = 0, 0
column, row = 0,0

sheet = pygame.Surface(screen_size)

for i in range(1,25):
    if i < 10:
        fn = "%s%i.png" % ("000", i)
    else:
        fn = "%s%i.png" % ("00", i)
    keyframe = pygame.image.load(fn)
    keyframe.set_colorkey(TRANSP_COLOR)
    x = column * SPRITE_SIZE
    y = row * SPRITE_SIZE 
    sheet.blit(keyframe, (x,y))
    if column + 1 == COLUMNS:
        column = 0
        row += 1
    else:
        column += 1


running = True
while running:
    pygame.display.update()
    screen.blit(sheet, (0,0))


    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            running = False
        if e.type == pygame.KEYDOWN:
            kname = pygame.key.name(e.key)
            if kname == 'q':
                running = False
            if kname == 's':
                pygame.image.save(screen, OUTPUT_FN)

pygame.quit()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM