sarxos / webcam-capture

The goal of this project is to allow integrated or USB-connected webcams to be accessed directly from Java. Using provided libraries users are able to read camera images and detect motion. Main project consist of several sub projects - the root one, which contains required classes, build-in webcam driver compatible with Windows, Linux and Mac OS, which can stream images as fast as your camera can serve them (up to 50 FPS). Main project can be used standalone, but user is able to replace build-in driver with different one - such as OpenIMAJ, GStreamer, V4L4j, JMF, LTI-CIVIL, FMJ, etc.
http://webcam-capture.sarxos.pl
MIT License
2.26k stars 1.11k forks source link

Webcam-Capture SWT implementation #91

Open sarxos opened 11 years ago

sarxos commented 11 years ago

Created on behalf of JD.


We have been trying to implement a video capture program using Lti-Civil and have gotten nowhere, within a few minutes of finding your project we had what we were looking for.

Well almost…

We are developing an application using Eclipse RCP; therefore we are using SWT. Would it be possible to implement the webcam-capture using SWT instead of AWT/Swing? As I said, I just found your project yesterday and haven’t spent much time with the code. If it is possible, I would certainly be willing to contribute the SWT implementation. I was just wondering if you knew of any known issues off the bat.

sarxos commented 11 years ago

Hi,

Yes, of course there is a possibility to add SWT support in the project. I was considering it some time ago, but I'm not familiar with SWT so that's why this support has never been implemented.

There are only few "real" Swing components existing in Webcam-Capture API. Those are WebcamPanel, WebcamPicker and few related classes. Of course there are other ones which depends strongly on AWT BufferedImage and cannot be changed without huge API changes, but I do not see any issue which would cause them to be rewriten in terms of additional SWT support. BufferedImage can be changed to SWT's ImageData before it is drawn on composite.

Please note that those two classes - WebcamPanel, WebcamPicker and WebcamViewer (which depends on the two previous ones) has been added as useful addons, the webcam-capture core is completely rendering-architecture independent - it's goal is simply to take picture from camera and return it to the user as BufferedImage.

Could you please elaborate more on the topic of what kind of functionality you would like to have in your Eclipse-based solution?

You have my support and I'm ready to help you with any kind of issues related to this enhancement.

jd-carroll commented 11 years ago

The original intention was to gain access to the thread that renders the image (in order to kill it once disposed). But I see that the issue #90 has been corrected. In addition the AWT_SWT bridge can be expensive (in terms of system resources).

Rewriting the BufferedImage might take more time than its worth, and as you said, that is a huge piece of the implementation.

So, my goal/intention would be providing a WebcamCanvas to replace the WebcamPanel, and provide more access to the underlying thread that redraws the image. The implementation would be a pure SWT based implementation (ie separate from Eclipse). Thus really making it more friendly to SWT based applications.

I think the first step would be looking at the process of converting BufferedImage into ImageData. I will try to spend a little time with that over the next couple of days and I will share my finds here.

dimitrios1988 commented 11 years ago
public static ImageData convertToSWT (BufferedImage bufferedImage) {
        if (bufferedImage.getColorModel() instanceof DirectColorModel) {
            DirectColorModel colorModel = (DirectColorModel) bufferedImage.getColorModel();
            PaletteData palette = new PaletteData(colorModel.getRedMask(), colorModel.getGreenMask(), colorModel.getBlueMask());
            ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette);
            WritableRaster raster = bufferedImage.getRaster();
            int[] pixelArray = new int[3];
            for (int y = 0; y < data.height; y++) {
                for (int x = 0; x < data.width; x++) {
                    raster.getPixel(x, y, pixelArray);
                    int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2]));
                    data.setPixel(x, y, pixel);
                }
            }
            return data;
        } else if (bufferedImage.getColorModel() instanceof IndexColorModel) {
            IndexColorModel colorModel = (IndexColorModel) bufferedImage.getColorModel();
            int size = colorModel.getMapSize();
            byte[] reds = new byte[size];
            byte[] greens = new byte[size];
            byte[] blues = new byte[size];
            colorModel.getReds(reds);
            colorModel.getGreens(greens);
            colorModel.getBlues(blues);
            RGB[] rgbs = new RGB[size];
            for (int i = 0; i < rgbs.length; i++) {
                rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
            }
            PaletteData palette = new PaletteData(rgbs);
            ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette);
            data.transparentPixel = colorModel.getTransparentPixel();
            WritableRaster raster = bufferedImage.getRaster();
            int[] pixelArray = new int[1];
            for (int y = 0; y < data.height; y++) {
                for (int x = 0; x < data.width; x++) {
                    raster.getPixel(x, y, pixelArray);
                    data.setPixel(x, y, pixelArray[0]);
                }
            }
            return data;
        }
        return null;
    }
sarxos commented 11 years ago

Hi, I'm not very familiar with SWT, so feel free to send patches :)

jd-carroll commented 11 years ago

Will do, I am working on some things internally right now and will hopefully get to this on Thursday or Friday.

I did look at the contribution from Chondrokoukis, and that looks good. My only question is if you developed that yourself or if that is opensource from someplace else? In either case, we should make sure we have the correct copyright listed.

Thanks,

JD

On Tue, May 7, 2013 at 4:08 AM, Bartosz Firyn notifications@github.comwrote:

Hi, I'm not very familiar with SWT, so feel free to send patches :)

— Reply to this email directly or view it on GitHubhttps://github.com/sarxos/webcam-capture/issues/91#issuecomment-17531410 .

sarxos commented 11 years ago

All the 3'rd party licenses for Webcam-Capture are included here and the main license is here. In terms of the SWT addon which I've started recently (link), it should include SWT license (EPL text). I hope that clarifies your question, but fell free to elaborate if you have any additional thought. I do not fully understand what are you referring as "developed that yourself".

jd-carroll commented 11 years ago

The code posted in comment 4 from dimitrious1988. That should solve the issue of converting the BufferedImage to the ImageData, but we need to know where it came from.

sarxos commented 11 years ago

The images obtained from Webcam Capture API has always DirectColorModel, so only first if statement is worth to be used.

I found this block to be used in many examples, in the similar, or exactly the same form, e.g.:

Therefore I doubt it should be licensed.

dimitrios1988 commented 11 years ago

I found it on the internet and thought that it would help, so I posted it...

sarxos commented 11 years ago

Hi @jd-carroll, @dimitrios1988,

I would like to ask you for help. Basing on the WebcamPanel code I prepared WebcamComposite counterpart for usage in SWT, but I stuck and have no idea how to fix the problem which I noticed.

The SWT webcam composite code can be found here.

The problem is that WebcamComposite I'm adding into Shell is not being displayed at all. I've tried to set different background to check whether it is painted, and I do not see any changes vs the previous attempt...

You are much more familiar with SWT, so could it be possible for you do debug this problem a little? Sorry about this, but that's my first code I ever wrote using SWT.

cncgoko commented 8 years ago

Hi,

I managed to use the SWT panel by simply adding the following in the constructor :

addPaintListener(this); 

I didn't try more or , and I get some flickering, but it works.