Skip to content

Commit ec8eb4c

Browse files
authored
* Add LibgdxFrameConverter to convert Frame to Libgdx Pixmap (pull #2315)
1 parent dedec82 commit ec8eb4c

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11

2+
* Add `LibgdxFrameConverter` to convert `Frame` to Libgdx `Pixmap` ([pull #2315](https://github.com/bytedeco/javacv/pull/2315))
23
* Fix `FFmpegFrameRecorder` dropped frame issues with audio samples ([pull #2307](https://github.com/bytedeco/javacv/pull/2307))
34
* Add `FrameFilter.videoFilterArgs/audioFilterArgs` properties to support multiple different inputs ([pull #2304](https://github.com/bytedeco/javacv/pull/2304))
45
* Ensure `FFmpegFrameGrabber.start()` skips over streams with no codecs ([issue #2299](https://github.com/bytedeco/javacv/issues/2299))

pom.xml

+7
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,13 @@
169169
<version>2.3.2</version>
170170
<optional>true</optional>
171171
</dependency>
172+
173+
<dependency>
174+
<groupId>com.badlogicgames.gdx</groupId>
175+
<artifactId>gdx</artifactId>
176+
<version>1.13.1</version>
177+
<optional>true</optional>
178+
</dependency>
172179
</dependencies>
173180

174181
<repositories>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Copyright (C) 2025 shan-luan
3+
*
4+
* Licensed either under the Apache License, Version 2.0, or (at your option)
5+
* under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation (subject to the "Classpath" exception),
7+
* either version 2, or any later version (collectively, the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
* http://www.gnu.org/licenses/
13+
* http://www.gnu.org/software/classpath/license.html
14+
*
15+
* or as provided in the LICENSE.txt file that accompanied this code.
16+
* Unless required by applicable law or agreed to in writing, software
17+
* distributed under the License is distributed on an "AS IS" BASIS,
18+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19+
* See the License for the specific language governing permissions and
20+
* limitations under the License.
21+
*/
22+
23+
package org.bytedeco.javacv;
24+
25+
import com.badlogic.gdx.graphics.Pixmap;
26+
27+
import java.nio.ByteBuffer;
28+
29+
/**
30+
* A utility class for converting between {@link Pixmap} and {@link Frame}.
31+
* The alpha channel is not converted and memory cannot be shared.
32+
*
33+
* @author shan-luan
34+
*/
35+
public class LibgdxFrameConverter extends FrameConverter<Pixmap> {
36+
/**
37+
* Converts a {@link Pixmap} to a {@link Frame}.
38+
*
39+
* @param pixmap the Pixmap to convert,RGBA8888 format
40+
* @return the converted Frame
41+
*/
42+
@Override
43+
public Frame convert(Pixmap pixmap) {
44+
if (pixmap == null) return null;
45+
46+
Frame frame = new Frame(pixmap.getWidth(), pixmap.getHeight(), Frame.DEPTH_UBYTE, 3, pixmap.getWidth() * 3);
47+
48+
ByteBuffer pixmapBuffer = pixmap.getPixels().duplicate();
49+
ByteBuffer frameBuffer = (ByteBuffer) frame.image[0];
50+
51+
int numPixels = pixmap.getWidth() * pixmap.getHeight();
52+
for (int i = 0; i < numPixels; i++) {
53+
byte r = pixmapBuffer.get();
54+
byte g = pixmapBuffer.get();
55+
byte b = pixmapBuffer.get();
56+
pixmapBuffer.position(pixmapBuffer.position() + 1);
57+
58+
frameBuffer.put(b);
59+
frameBuffer.put(g);
60+
frameBuffer.put(r);
61+
}
62+
63+
frameBuffer.flip();
64+
return frame;
65+
}
66+
67+
/**
68+
* Converts a {@link Frame} to a {@link Pixmap}.
69+
*
70+
* @param frame the Frame to convert
71+
* @return the converted Pixmap, RGBA8888 format
72+
*/
73+
@Override
74+
public Pixmap convert(Frame frame) {
75+
if (frame == null || frame.image[0] == null) return null;
76+
Pixmap pixmap = new Pixmap(frame.imageWidth, frame.imageHeight, Pixmap.Format.RGBA8888);
77+
ByteBuffer frameBuffer = ((ByteBuffer) frame.image[0]).duplicate();
78+
ByteBuffer pixmapBuffer = pixmap.getPixels();
79+
pixmapBuffer.position(0);
80+
frameBuffer.rewind();
81+
82+
int numPixels = frame.imageWidth * frame.imageHeight;
83+
for (int i = 0; i < numPixels; i++) {
84+
byte b = frameBuffer.get();
85+
byte g = frameBuffer.get();
86+
byte r = frameBuffer.get();
87+
88+
pixmapBuffer.put(r);
89+
pixmapBuffer.put(g);
90+
pixmapBuffer.put(b);
91+
pixmapBuffer.put((byte) -1);// alpha always set to 255
92+
}
93+
94+
pixmapBuffer.flip();
95+
return pixmap;
96+
}
97+
98+
/**
99+
* Converts a {@link Frame} to a {@link Pixmap}.
100+
* Available only when the format of the Frame is {@link org.bytedeco.ffmpeg.global.avutil
101+
* #AV_PIX_FMT_RGBA}.
102+
* Faster than {@link #convert(Frame)}
103+
*
104+
* @param frame the Frame to convert
105+
* @return the converted Pixmap, RGBA8888 format
106+
*/
107+
public Pixmap fastConvert(Frame frame) {
108+
if (frame == null || frame.image[0] == null) return null;
109+
110+
Pixmap pixmap = new Pixmap(frame.imageWidth, frame.imageHeight, Pixmap.Format.RGBA8888);
111+
ByteBuffer frameBuffer = ((ByteBuffer) frame.image[0]).duplicate();
112+
ByteBuffer pixmapBuffer = pixmap.getPixels();
113+
pixmapBuffer.position(0);
114+
frameBuffer.rewind();
115+
pixmapBuffer.put(frameBuffer);
116+
pixmapBuffer.flip();
117+
return pixmap;
118+
}
119+
}

0 commit comments

Comments
 (0)