diff --git a/CHANGELOG.md b/CHANGELOG.md
index 07f055ae..3dbb0300 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,5 @@
+ * Add `LibgdxFrameConverter` to convert `Frame` to Libgdx `Pixmap` ([pull #2315](https://github.com/bytedeco/javacv/pull/2315))
* Fix `FFmpegFrameRecorder` dropped frame issues with audio samples ([pull #2307](https://github.com/bytedeco/javacv/pull/2307))
* Add `FrameFilter.videoFilterArgs/audioFilterArgs` properties to support multiple different inputs ([pull #2304](https://github.com/bytedeco/javacv/pull/2304))
* Ensure `FFmpegFrameGrabber.start()` skips over streams with no codecs ([issue #2299](https://github.com/bytedeco/javacv/issues/2299))
diff --git a/pom.xml b/pom.xml
index bf0afdf2..8a004a76 100644
--- a/pom.xml
+++ b/pom.xml
@@ -169,6 +169,13 @@
2.3.2
true
+
+
+ com.badlogicgames.gdx
+ gdx
+ 1.13.1
+ true
+
diff --git a/src/main/java/org/bytedeco/javacv/LibgdxFrameConverter.java b/src/main/java/org/bytedeco/javacv/LibgdxFrameConverter.java
new file mode 100644
index 00000000..9135044b
--- /dev/null
+++ b/src/main/java/org/bytedeco/javacv/LibgdxFrameConverter.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2025 shan-luan
+ *
+ * Licensed either under the Apache License, Version 2.0, or (at your option)
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation (subject to the "Classpath" exception),
+ * either version 2, or any later version (collectively, the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.gnu.org/licenses/
+ * http://www.gnu.org/software/classpath/license.html
+ *
+ * or as provided in the LICENSE.txt file that accompanied this code.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.bytedeco.javacv;
+
+import com.badlogic.gdx.graphics.Pixmap;
+
+import java.nio.ByteBuffer;
+
+/**
+ * A utility class for converting between {@link Pixmap} and {@link Frame}.
+ * The alpha channel is not converted and memory cannot be shared.
+ *
+ * @author shan-luan
+ */
+public class LibgdxFrameConverter extends FrameConverter {
+ /**
+ * Converts a {@link Pixmap} to a {@link Frame}.
+ *
+ * @param pixmap the Pixmap to convert,RGBA8888 format
+ * @return the converted Frame
+ */
+ @Override
+ public Frame convert(Pixmap pixmap) {
+ if (pixmap == null) return null;
+
+ Frame frame = new Frame(pixmap.getWidth(), pixmap.getHeight(), Frame.DEPTH_UBYTE, 3, pixmap.getWidth() * 3);
+
+ ByteBuffer pixmapBuffer = pixmap.getPixels().duplicate();
+ ByteBuffer frameBuffer = (ByteBuffer) frame.image[0];
+
+ int numPixels = pixmap.getWidth() * pixmap.getHeight();
+ for (int i = 0; i < numPixels; i++) {
+ byte r = pixmapBuffer.get();
+ byte g = pixmapBuffer.get();
+ byte b = pixmapBuffer.get();
+ pixmapBuffer.position(pixmapBuffer.position() + 1);
+
+ frameBuffer.put(b);
+ frameBuffer.put(g);
+ frameBuffer.put(r);
+ }
+
+ frameBuffer.flip();
+ return frame;
+ }
+
+ /**
+ * Converts a {@link Frame} to a {@link Pixmap}.
+ *
+ * @param frame the Frame to convert
+ * @return the converted Pixmap, RGBA8888 format
+ */
+ @Override
+ public Pixmap convert(Frame frame) {
+ if (frame == null || frame.image[0] == null) return null;
+ Pixmap pixmap = new Pixmap(frame.imageWidth, frame.imageHeight, Pixmap.Format.RGBA8888);
+ ByteBuffer frameBuffer = ((ByteBuffer) frame.image[0]).duplicate();
+ ByteBuffer pixmapBuffer = pixmap.getPixels();
+ pixmapBuffer.position(0);
+ frameBuffer.rewind();
+
+ int numPixels = frame.imageWidth * frame.imageHeight;
+ for (int i = 0; i < numPixels; i++) {
+ byte b = frameBuffer.get();
+ byte g = frameBuffer.get();
+ byte r = frameBuffer.get();
+
+ pixmapBuffer.put(r);
+ pixmapBuffer.put(g);
+ pixmapBuffer.put(b);
+ pixmapBuffer.put((byte) -1);// alpha always set to 255
+ }
+
+ pixmapBuffer.flip();
+ return pixmap;
+ }
+
+ /**
+ * Converts a {@link Frame} to a {@link Pixmap}.
+ * Available only when the format of the Frame is {@link org.bytedeco.ffmpeg.global.avutil
+ * #AV_PIX_FMT_RGBA}.
+ * Faster than {@link #convert(Frame)}
+ *
+ * @param frame the Frame to convert
+ * @return the converted Pixmap, RGBA8888 format
+ */
+ public Pixmap fastConvert(Frame frame) {
+ if (frame == null || frame.image[0] == null) return null;
+
+ Pixmap pixmap = new Pixmap(frame.imageWidth, frame.imageHeight, Pixmap.Format.RGBA8888);
+ ByteBuffer frameBuffer = ((ByteBuffer) frame.image[0]).duplicate();
+ ByteBuffer pixmapBuffer = pixmap.getPixels();
+ pixmapBuffer.position(0);
+ frameBuffer.rewind();
+ pixmapBuffer.put(frameBuffer);
+ pixmapBuffer.flip();
+ return pixmap;
+ }
+}