All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.webswing.javafx.toolkit.util.WebFxUtil Maven / Gradle / Ivy

There is a newer version: 20.2.4
Show newest version
package org.webswing.javafx.toolkit.util;

import com.sun.glass.ui.Pixels;
import com.sun.javafx.geom.RectBounds;
import org.w3c.dom.css.Rect;
import org.webswing.toolkit.util.DeamonThreadFactory;
import org.webswing.toolkit.util.Logger;

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.*;

/**
 * Created by vikto on 06-Mar-17.
 */
public class WebFxUtil {

	private static final int SQ = 45;
	private static final int threadCount = Runtime.getRuntime().availableProcessors();
	private static ExecutorService processorPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), DeamonThreadFactory.getInstance("Webswing JavaFx Pixel processor"));

	public static BufferedImage pixelsToImage(BufferedImage image, Pixels pixels) {
		Pixels p = pixels;
		if (p != null) {
			Buffer data = p.getPixels();
			int width = p.getWidth();
			int height = p.getHeight();
			if (p.getBytesPerComponent() == 1) {
				ByteBuffer bytes = (ByteBuffer) data;
				return paintByte(width, height, bytes, image);
			} else {
				IntBuffer ints = (IntBuffer) data;
				return paintInt(width, height, ints, image);
			}
		}
		return null;
	}

	private static BufferedImage paintInt(int width, int height, IntBuffer ints, BufferedImage image) {
		if (image == null || image.getWidth() != width || image.getHeight() != height || image.getType() != BufferedImage.TYPE_INT_ARGB) {
			image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
		}
		DataBufferInt dataBuf = (DataBufferInt) image.getRaster().getDataBuffer();
		ints.get(dataBuf.getData(), 0, width * height);
		return image;
	}

	private static BufferedImage paintByte(int width, int height, ByteBuffer bytes, BufferedImage image) {
		if (image == null || image.getWidth() != width || image.getHeight() != height || image.getType() != BufferedImage.TYPE_4BYTE_ABGR) {
			image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
		}
		DataBufferByte dataBuf = (DataBufferByte) image.getRaster().getDataBuffer();
		bytes.get(dataBuf.getData(), 0, width * height);
		return image;
	}

	public static Set findUpdateAreas(BufferedImage image, BufferedImage previous, Set tmpBounds) {
		int width = image.getWidth();
		int height = image.getHeight();
		List toCompare = new ArrayList<>();
		for (int c = 0; c <= width / SQ; c++) {
			for (int r = 0; r <= height / SQ; r++) {
				int x = Math.min(c * SQ, width - 1), y = Math.min(r * SQ, height - 1);
				int w = Math.min(x + SQ, width), h = Math.min(y + SQ, height);
				if (tmpBounds != null) {
					for (RectBounds bound : tmpBounds) {
						if (bound.intersects(x, y, w, h)) {
							toCompare.add(new RectBounds(x, y, w, h));
						}
					}
				} else {
					toCompare.add(new RectBounds(x, y, w, h));
				}
			}
		}
		List>> futures = new ArrayList<>();
		for (int i = 0; i < threadCount; i++) {
			final int currentoffset = i;
			futures.add(processorPool.submit(new Callable>() {
				int offset = currentoffset;

				@Override
				public List call() throws Exception {
					List diff = new ArrayList<>();

					int[] imgData = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
					int[] prevData = ((DataBufferInt) previous.getRaster().getDataBuffer()).getData();
					for (int j = offset; j < toCompare.size(); j = j + threadCount) {
						RectBounds currentArea = toCompare.get(j);

						areaCompare:
						for (int x = (int) currentArea.getMinX(); x < currentArea.getMaxX(); x++) {
							for (int y = (int) currentArea.getMinY(); y < currentArea.getMaxY(); y++) {
								int offset = y * width + x;
								try {
									if (imgData[offset] != prevData[offset]) {
										diff.add(currentArea);
										break areaCompare;
									}
								} catch (Exception e) {
									Logger.error("failed to comapare: offset" + offset + "|" + x + "|" + y + "|" + width + "|" + height + "| size" + imgData.length);
								}
							}
						}
					}
					return diff;
				}
			}));
		}

		//collect results:
		Set completeResult = new HashSet<>();
		for (Future> f : futures) {
			try {
				completeResult.addAll(f.get());
			} catch (Exception e) {
				Logger.error("failed to compare pixels", e);
			}
		}
		return completeResult;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy