diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..30e3b31 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +/sandbox/** +/.idea/** +/*.iml +/.git/** +/jars/** +/bundle/** +/.gradle/** +/vendor/** +/build/** +/examples/vendor/** +/package.hub.yml +/gradle +/build.gradle +/gradlew +/gradlew.bat +/package-lock.php.yml +/out/** +/dn-sources/** \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f49a4e1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (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 + + 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. \ No newline at end of file diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..96afda1 --- /dev/null +++ b/README.MD @@ -0,0 +1,49 @@ +# Webcam +Расширение для работы с веб-камерой +## Установка +``` +jppm add jphp-webcam-ext +``` +## Примеры +### Получить веб-камеру по умолчанию: +```php +$webcam = Webcam::getDefault(); +``` +### Получить список веб-камер: +```php +$webcamList = Webcam::getWebcams(); +``` +### Сделать снимок с веб-камеры: +```php +$webcam = Webcam::getDefault(); +$webcam->open(); +$image = $webcam->getImage(); +$image->save('screenshot.png'); +``` +### Отобразить изображение с веб-камеры: +```php +$webcam = Webcam::getDefault(); +$webcam->open(); + +$webcamView = new UXWebcamView(); +$webcamView->webcam = $webcam; +$webcamView->size = [640, 480]; +$form->add($webcamView); +$webcamView->play(); +``` +## Расширение для DevelNext +[Скачать](https://github.com/jphp-group/jphp-webcam-ext/releases/latest) + +![](/screenshots/dn_view.png) + +## Скриншоты + +![](/screenshots/screenshot.png) + +## Дополнительно + +[Venity](https://vk.com/venity) + +[DevelNext - extensions & manuals.](https://vk.com/dn_extension) + +[Оригинальная библиотека](https://github.com/sarxos/webcam-capture) \ No newline at end of file diff --git a/api-docs/README.md b/api-docs/README.md new file mode 100644 index 0000000..ef77325 --- /dev/null +++ b/api-docs/README.md @@ -0,0 +1,25 @@ +## jphp-webcam-ext +> version 1.0.0, created by JPPM. + + +### Install +``` +jppm add jphp-webcam-ext@1.0.0 +``` + +### API +**Classes** + +#### `php\gui` + +- [`UXWebcamView`](https://github.com/jphp-group/jphp-webcam-ext/api-docs/classes/php/gui/UXWebcamView.md) + +#### `webcam\event` + +- [`WebcamDiscoveryEvent`](https://github.com/jphp-group/jphp-webcam-ext/api-docs/classes/webcam/event/WebcamDiscoveryEvent.md) +- [`WebcamMotionEvent`](https://github.com/jphp-group/jphp-webcam-ext/api-docs/classes/webcam/event/WebcamMotionEvent.md) + +#### `webcam` + +- [`Webcam`](https://github.com/jphp-group/jphp-webcam-ext/api-docs/classes/webcam/Webcam.md) +- [`WebcamMotionDetector`](https://github.com/jphp-group/jphp-webcam-ext/api-docs/classes/webcam/WebcamMotionDetector.md) \ No newline at end of file diff --git a/api-docs/classes/php/gui/UXWebcamView.md b/api-docs/classes/php/gui/UXWebcamView.md new file mode 100644 index 0000000..df7697d --- /dev/null +++ b/api-docs/classes/php/gui/UXWebcamView.md @@ -0,0 +1,44 @@ +# UXWebcamView + +- **class** `UXWebcamView` (`php\gui\UXWebcamView`) **extends** `UXControl` (`php\gui\UXControl`) +- **source** `php/gui/UXWebcamView.php` + +--- + +#### Properties + +- `->`[`webcam`](#prop-webcam) : [`Webcam`](https://github.com/jphp-group/jphp-webcam-ext/api-docs/classes/webcam/Webcam.md) +- `->`[`placeholderColor`](#prop-placeholdercolor) : `UXColor` +- `->`[`openMode`](#prop-openmode) : `string` +- `->`[`closeMode`](#prop-closemode) : `string` +- `->`[`stretch`](#prop-stretch) : `bool` +- `->`[`centered`](#prop-centered) : `bool` +- `->`[`stopped`](#prop-stopped) : `bool` +- `->`[`flipX`](#prop-flipx) : `bool` +- `->`[`flipY`](#prop-flipy) : `bool` + +--- + +#### Methods + +- `->`[`play()`](#method-play) +- `->`[`stop()`](#method-stop) + +--- +# Methods + + + +### play() +```php +play(): void +``` + +--- + + + +### stop() +```php +stop(): void +``` \ No newline at end of file diff --git a/api-docs/classes/webcam/Webcam.md b/api-docs/classes/webcam/Webcam.md new file mode 100644 index 0000000..509020d --- /dev/null +++ b/api-docs/classes/webcam/Webcam.md @@ -0,0 +1,114 @@ +# Webcam + +- **class** `Webcam` (`webcam\Webcam`) +- **source** `webcam/Webcam.php` + +--- + +#### Properties + +- `->`[`name`](#prop-name) : `string` +- `->`[`open`](#prop-open) : `bool` +- `->`[`viewSize`](#prop-viewsize) : `array` + +--- + +#### Static Methods + +- `Webcam ::`[`getDefault()`](#method-getdefault) +- `Webcam ::`[`getWebcams()`](#method-getwebcams) +- `Webcam ::`[`addWebcamFoundListener()`](#method-addwebcamfoundlistener) +- `Webcam ::`[`addWebcamGoneListener()`](#method-addwebcamgonelistener) +- `Webcam ::`[`removeWebcamFoundListener()`](#method-removewebcamfoundlistener) +- `Webcam ::`[`removeWebcamGoneListener()`](#method-removewebcamgonelistener) + +--- + +#### Methods + +- `->`[`open()`](#method-open) +- `->`[`close()`](#method-close) +- `->`[`getImage()`](#method-getimage) + +--- +# Static Methods + + + +### getDefault() +```php +Webcam::getDefault(int $timeout): Webcam +``` + +--- + + + +### getWebcams() +```php +Webcam::getWebcams(int $timeout): Webcam[] +``` + +--- + + + +### addWebcamFoundListener() +```php +Webcam::addWebcamFoundListener(callable $callable): Invoker +``` + +--- + + + +### addWebcamGoneListener() +```php +Webcam::addWebcamGoneListener(callable $callable): Invoker +``` + +--- + + + +### removeWebcamFoundListener() +```php +Webcam::removeWebcamFoundListener(php\lang\Invoker $callable): void +``` + +--- + + + +### removeWebcamGoneListener() +```php +Webcam::removeWebcamGoneListener(php\lang\Invoker $callable): void +``` + +--- +# Methods + + + +### open() +```php +open(boolean $async): void +``` + +--- + + + +### close() +```php +close(): void +``` + +--- + + + +### getImage() +```php +getImage(): UXImage +``` \ No newline at end of file diff --git a/api-docs/classes/webcam/WebcamMotionDetector.md b/api-docs/classes/webcam/WebcamMotionDetector.md new file mode 100644 index 0000000..14bd767 --- /dev/null +++ b/api-docs/classes/webcam/WebcamMotionDetector.md @@ -0,0 +1,111 @@ +# WebcamMotionDetector + +- **class** `WebcamMotionDetector` (`webcam\WebcamMotionDetector`) +- **source** `webcam/WebcamMotionDetector.php` + +--- + +#### Properties + +- `->`[`interval`](#prop-interval) : `int` +- `->`[`maxMotionPoints`](#prop-maxmotionpoints) : `int` +- `->`[`pointRange`](#prop-pointrange) : `int` +- `->`[`motionArea`](#prop-motionarea) : `float` +- `->`[`motion`](#prop-motion) : `bool` +- `->`[`webcam`](#prop-webcam) : [`Webcam`](https://github.com/jphp-group/jphp-webcam-ext/api-docs/classes/webcam/Webcam.md) + +--- + +#### Methods + +- `->`[`__construct()`](#method-__construct) +- `->`[`start()`](#method-start) +- `->`[`stop()`](#method-stop) +- `->`[`setPixelThreshold()`](#method-setpixelthreshold) +- `->`[`setAreaThreshold()`](#method-setareathreshold) +- `->`[`setInertia()`](#method-setinertia) +- `->`[`clearInertia()`](#method-clearinertia) +- `->`[`addMotionListener()`](#method-addmotionlistener) +- `->`[`removeMotionListener()`](#method-removemotionlistener) + +--- +# Methods + + + +### __construct() +```php +__construct(webcam\Webcam $webcam): void +``` + +--- + + + +### start() +```php +start(): void +``` + +--- + + + +### stop() +```php +stop(): void +``` + +--- + + + +### setPixelThreshold() +```php +setPixelThreshold(int $value): void +``` + +--- + + + +### setAreaThreshold() +```php +setAreaThreshold(double $value): void +``` + +--- + + + +### setInertia() +```php +setInertia(int $value): void +``` + +--- + + + +### clearInertia() +```php +clearInertia(): void +``` + +--- + + + +### addMotionListener() +```php +addMotionListener(callable $callable): Invoker +``` + +--- + + + +### removeMotionListener() +```php +removeMotionListener(php\lang\Invoker $invoker): void +``` \ No newline at end of file diff --git a/api-docs/classes/webcam/event/WebcamDiscoveryEvent.md b/api-docs/classes/webcam/event/WebcamDiscoveryEvent.md new file mode 100644 index 0000000..48300ab --- /dev/null +++ b/api-docs/classes/webcam/event/WebcamDiscoveryEvent.md @@ -0,0 +1,36 @@ +# WebcamDiscoveryEvent + +- **class** `WebcamDiscoveryEvent` (`webcam\event\WebcamDiscoveryEvent`) +- **source** `webcam/event/WebcamDiscoveryEvent.php` + +--- + +#### Properties + +- `->`[`webcam`](#prop-webcam) : `Webcam` + +--- + +#### Methods + +- `->`[`isAdded()`](#method-isadded) +- `->`[`isRemoved()`](#method-isremoved) + +--- +# Methods + + + +### isAdded() +```php +isAdded(): bool +``` + +--- + + + +### isRemoved() +```php +isRemoved(): bool +``` \ No newline at end of file diff --git a/api-docs/classes/webcam/event/WebcamMotionEvent.md b/api-docs/classes/webcam/event/WebcamMotionEvent.md new file mode 100644 index 0000000..05a235f --- /dev/null +++ b/api-docs/classes/webcam/event/WebcamMotionEvent.md @@ -0,0 +1,15 @@ +# WebcamMotionEvent + +- **class** `WebcamMotionEvent` (`webcam\event\WebcamMotionEvent`) +- **source** `webcam/event/WebcamMotionEvent.php` + +--- + +#### Properties + +- `->`[`webcam`](#prop-webcam) : [`Webcam`](https://github.com/jphp-group/jphp-webcam-ext/api-docs/classes/webcam/Webcam.md) +- `->`[`area`](#prop-area) : `float` +- `->`[`cog`](#prop-cog) : `array` +- `->`[`points`](#prop-points) : `array[]` +- `->`[`currentImage`](#prop-currentimage) : `UXImage` +- `->`[`previousImage`](#prop-previousimage) : `UXImage` \ No newline at end of file diff --git a/package.php.yml b/package.php.yml new file mode 100644 index 0000000..3d516e1 --- /dev/null +++ b/package.php.yml @@ -0,0 +1,50 @@ +name: jphp-webcam-ext +version: 1.0.3 + +plugins: +- Hub +- Doc +- Gradle + +deps: + jphp-runtime: '*' + jphp-gui-ext: '*' + +devDeps: + jphp-core: '*' + dn-bundle-plugin: '*' + + +gradle: + deps: + - 'com.github.sarxos:webcam-capture:0.3.12' + +config: + ignore: + - /sandbox/** + - /.idea/** + - /*.iml + - /.git/** + - /package.hub.yml + - /bundle/** + - /src-bundle/** + - /build + - /out/** + - /examples/** + - /screenshots/** + - /dn-sources/** + - /.gitignore + - /settings.gradle + +doc: + url-prefix: 'https://github.com/jphp-group/%name%/api-docs/' + + +develnext-bundle: + version: 1.0.2 + name: Webcam + author: broelik + icon: "develnext/bundle/webcam/icon32.png" + description: "Пакет для работы с веб-камерой" + group: "other" + class: "develnext\\bundle\\webcam\\WebcamBundle" \ No newline at end of file diff --git a/screenshots/dn_view.png b/screenshots/dn_view.png new file mode 100644 index 0000000..d1e8a7f Binary files /dev/null and b/screenshots/dn_view.png differ diff --git a/screenshots/screenshot.png b/screenshots/screenshot.png new file mode 100644 index 0000000..43e96a7 Binary files /dev/null and b/screenshots/screenshot.png differ diff --git a/sdk/php/gui/UXWebcamView.php b/sdk/php/gui/UXWebcamView.php new file mode 100644 index 0000000..ec6b3a4 --- /dev/null +++ b/sdk/php/gui/UXWebcamView.php @@ -0,0 +1,50 @@ +getRegisteredFormat(GuiFormFormat::class); + if($format){ + $format->registerInternalList('.dn/bundle/webcam/formComponents'); + } + } + function onRemove(Project $project, AbstractBundle $owner = null){ + parent::onRemove($project, $owner); + /** @var GuiFormFormat $format */ + $format = Ide::get()->getRegisteredFormat(GuiFormFormat::class); + if($format){ + $format->unregisterInternalList('.dn/bundle/webcam/formComponents'); + } + } + public function onRegister(IdeLibraryBundleResource $resource) + { + parent::onRegister($resource); + + $jars = ['bridj', 'slf4j-api', 'webcam-capture', 'jphp-webcam-ext']; + $files = fs::scan($resource->getPath(), null); + $filesToAdd = []; + foreach($files as $j => $file){ + if(str::startsWith($file->getName(), 'dn-')){ + continue; + } + foreach($jars as $i => $jar){ + if(str::contains($file->getName(), $jar)){ + $filesToAdd[$i] = $file; + unset($jars[$i]); + unset($files[$j]); + break; + } + } + } + $filesToAdd = arr::sortByKeys($filesToAdd); + + + try{ + foreach($filesToAdd as $file){ + Runtime::addJar($file); + } + } + catch(\Throwable $e){ + file_put_contents('c:/users/broelik/desktop/result.txt', $e->getMessage()); + } + } +} \ No newline at end of file diff --git a/src-bundle/develnext/bundle/webcam/elements/WebcamViewFormElement.php b/src-bundle/develnext/bundle/webcam/elements/WebcamViewFormElement.php new file mode 100644 index 0000000..a1a31a3 --- /dev/null +++ b/src-bundle/develnext/bundle/webcam/elements/WebcamViewFormElement.php @@ -0,0 +1,44 @@ +placeholderColor = 'black'; + return $view; + } + public function getDefaultSize(){ + return [300, 200]; + } + public function isOrigin($any){ + return get_class($any) == UXWebcamView::class; + } +} \ No newline at end of file diff --git a/src-bundle/develnext/bundle/webcam/elements/WebcamViewFormElement.xml b/src-bundle/develnext/bundle/webcam/elements/WebcamViewFormElement.xml new file mode 100644 index 0000000..98b6ca2 --- /dev/null +++ b/src-bundle/develnext/bundle/webcam/elements/WebcamViewFormElement.xml @@ -0,0 +1,24 @@ + + + + + Не открывать + Открывать синхронно + Открывать асинхронно + + + + + Не закрывать + Закрывать синхронно + Закрывать асинхронно + + + + + + + + + + \ No newline at end of file diff --git a/src-bundle/develnext/bundle/webcam/tags/WebcamViewFormElementTag.php b/src-bundle/develnext/bundle/webcam/tags/WebcamViewFormElementTag.php new file mode 100644 index 0000000..ee8123d --- /dev/null +++ b/src-bundle/develnext/bundle/webcam/tags/WebcamViewFormElementTag.php @@ -0,0 +1,31 @@ +setAttribute('openMode', $node->openMode); + $element->setAttribute('closeMode', $node->closeMode); + $element->setAttribute('stretch', $node->stretch ? 'true' : 'false'); + $element->setAttribute('centered', $node->centered ? 'true' : 'false'); + $element->setAttribute('flipX', $node->flipX ? 'true' : 'false'); + $element->setAttribute('flipY', $node->flipY ? 'true' : 'false'); + if($node->placeholderColor){ + $element->setAttribute('placeholderFill', $node->placeholderColor->getWebValue()); + } + } +} \ No newline at end of file diff --git a/src-jvm/main/java/org/develnext/jphp/ext/webcam/WebcamExtension.java b/src-jvm/main/java/org/develnext/jphp/ext/webcam/WebcamExtension.java new file mode 100644 index 0000000..89cdc7e --- /dev/null +++ b/src-jvm/main/java/org/develnext/jphp/ext/webcam/WebcamExtension.java @@ -0,0 +1,38 @@ +package org.develnext.jphp.ext.webcam; + +import com.github.sarxos.webcam.Webcam; +import com.github.sarxos.webcam.WebcamDiscoveryEvent; +import com.github.sarxos.webcam.WebcamMotionDetector; +import com.github.sarxos.webcam.WebcamMotionEvent; +import org.develnext.jphp.ext.webcam.classes.WebcamMotionDetectorWrapper; +import org.develnext.jphp.ext.webcam.classes.event.WebcamDiscoveryEventWrapper; +import org.develnext.jphp.ext.webcam.classes.event.WebcamMotionEventWrapper; +import org.develnext.jphp.ext.webcam.classes.gui.WebcamViewWrapper; +import org.develnext.jphp.ext.webcam.classes.WebcamWrapper; +import org.develnext.jphp.ext.webcam.support.control.WebcamView; +import org.develnext.jphp.ext.webcam.support.memory.WebcamViewModeMemoryOperation; +import php.runtime.env.CompileScope; +import php.runtime.ext.support.Extension; +import php.runtime.memory.support.MemoryOperation; + +public class WebcamExtension extends Extension { + public static final String NS = "webcam"; + + @Override + public Status getStatus() { + return Status.EXPERIMENTAL; + } + + @Override + public void onRegister(CompileScope scope) { + registerWrapperClass(scope, WebcamView.class, WebcamViewWrapper.class); + MemoryOperation.register(new WebcamViewModeMemoryOperation()); + + + registerWrapperClass(scope, Webcam.class, WebcamWrapper.class); + registerWrapperClass(scope, WebcamMotionDetector.class, WebcamMotionDetectorWrapper.class); + + registerWrapperClass(scope, WebcamDiscoveryEvent.class, WebcamDiscoveryEventWrapper.class); + registerWrapperClass(scope, WebcamMotionEvent.class, WebcamMotionEventWrapper.class); + } +} \ No newline at end of file diff --git a/src-jvm/main/java/org/develnext/jphp/ext/webcam/classes/WebcamMotionDetectorWrapper.java b/src-jvm/main/java/org/develnext/jphp/ext/webcam/classes/WebcamMotionDetectorWrapper.java new file mode 100644 index 0000000..a733c13 --- /dev/null +++ b/src-jvm/main/java/org/develnext/jphp/ext/webcam/classes/WebcamMotionDetectorWrapper.java @@ -0,0 +1,80 @@ +package org.develnext.jphp.ext.webcam.classes; + +import com.github.sarxos.webcam.Webcam; +import com.github.sarxos.webcam.WebcamDiscoveryListener; +import com.github.sarxos.webcam.WebcamMotionDetector; +import com.github.sarxos.webcam.WebcamMotionListener; +import org.develnext.jphp.ext.webcam.WebcamExtension; +import php.runtime.annotation.Reflection; +import php.runtime.env.Environment; +import php.runtime.ext.core.classes.WrapInvoker; +import php.runtime.invoke.Invoker; +import php.runtime.lang.BaseWrapper; +import php.runtime.memory.ArrayMemory; +import php.runtime.reflection.ClassEntity; + +import java.awt.*; + +@Reflection.Name("WebcamMotionDetector") +@Reflection.Namespace(WebcamExtension.NS) +public class WebcamMotionDetectorWrapper extends BaseWrapper { + public WebcamMotionDetectorWrapper(Environment env, WebcamMotionDetector wrappedObject) { + super(env, wrappedObject); + } + public WebcamMotionDetectorWrapper(Environment env, ClassEntity clazz) { + super(env, clazz); + } + interface WrappedInterface{ + void start(); + void stop(); + + @Reflection.Getter int getInterval(); + @Reflection.Getter int getMaxMotionPoints(); + @Reflection.Getter int getPointRange(); + @Reflection.Getter double getMotionArea(); + @Reflection.Getter("motion") boolean isMotion(); + @Reflection.Getter Webcam getWebcam(); + + @Reflection.Setter void setInterval(int value); + + @Reflection.Signature void setPixelThreshold(int value); + @Reflection.Signature void setMaxMotionPoints(int value); + @Reflection.Signature void setPointRange(int value); + @Reflection.Signature void setInertia(int value); + @Reflection.Signature void setAreaThreshold(double value); + } + + @Reflection.Signature + public void __construct(Webcam webcam){ + __wrappedObject = new WebcamMotionDetector(webcam); + } + @Reflection.Getter + public ArrayMemory getMotionCog(){ + ArrayMemory result = new ArrayMemory(); + + Point cog = getWrappedObject().getMotionCog(); + + result.add(cog.getX()); + result.add(cog.getY()); + + return result; + } + + @Reflection.Signature + public WrapInvoker addMotionListener(Environment env, Invoker invoker){ + WebcamMotionListener listener = (e) -> invoker.callAny(e); + + getWrappedObject().addMotionListener(listener); + + WrapInvoker wrapInvoker = new WrapInvoker(env, invoker); + invoker.setUserData(listener); + return wrapInvoker; + } + @Reflection.Signature + public boolean removeMotionListener(Invoker invoker){ + if(invoker.getUserData() instanceof WebcamMotionListener){ + return getWrappedObject().removeMotionListener((WebcamMotionListener)invoker.getUserData()); + } + return false; + } +} diff --git a/src-jvm/main/java/org/develnext/jphp/ext/webcam/classes/WebcamWrapper.java b/src-jvm/main/java/org/develnext/jphp/ext/webcam/classes/WebcamWrapper.java new file mode 100644 index 0000000..c4b6e10 --- /dev/null +++ b/src-jvm/main/java/org/develnext/jphp/ext/webcam/classes/WebcamWrapper.java @@ -0,0 +1,129 @@ +package org.develnext.jphp.ext.webcam.classes; + +import com.github.sarxos.webcam.Webcam; +import com.github.sarxos.webcam.WebcamDiscoveryEvent; +import com.github.sarxos.webcam.WebcamDiscoveryListener; +import javafx.beans.value.ChangeListener; +import javafx.embed.swing.SwingFXUtils; +import javafx.scene.image.Image; +import org.develnext.jphp.ext.javafx.JavaFXExtension; +import org.develnext.jphp.ext.webcam.WebcamExtension; +import php.runtime.Memory; +import php.runtime.annotation.Reflection; +import php.runtime.env.Environment; +import php.runtime.ext.core.classes.WrapInvoker; +import php.runtime.invoke.Invoker; +import php.runtime.lang.BaseWrapper; +import php.runtime.memory.ArrayMemory; +import php.runtime.reflection.ClassEntity; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeoutException; + + +@Reflection.Name("Webcam") +@Reflection.Namespace(WebcamExtension.NS) +@Reflection.Abstract +public class WebcamWrapper extends BaseWrapper { + public WebcamWrapper(Environment env, Webcam wrappedObject) { + super(env, wrappedObject); + } + public WebcamWrapper(Environment env, ClassEntity clazz) { + super(env, clazz); + } + interface WrappedInterface{ + boolean open(); + boolean open(boolean async); + boolean close(); + + @Reflection.Getter("open") boolean isOpen(); + @Reflection.Getter boolean getName(); + } + + @Reflection.Getter + public Memory getViewSize(){ + Dimension dimension = getWrappedObject().getViewSize(); + if(dimension == null){ + return Memory.NULL; + } + + ArrayMemory res = new ArrayMemory(); + res.refOfIndex("width").assign(dimension.getWidth()); + res.refOfIndex("height").assign(dimension.getHeight()); + + return res; + } + + @Reflection.Signature + public Image getImage(){ + BufferedImage bufferedImage = getWrappedObject().getImage(); + if(bufferedImage == null){ + return null; + } + + return SwingFXUtils.toFXImage(bufferedImage, null); + } + + + @Reflection.Signature + public static Webcam getDefault(){ + return Webcam.getDefault(); + } + @Reflection.Signature + public static Webcam getDefault(long timeout) throws TimeoutException{ + return Webcam.getDefault(timeout); + } + + @Reflection.Signature + public static List getWebcams(){ + return Webcam.getWebcams(); + } + @Reflection.Signature + public static List getWebcams(long timeout) throws TimeoutException { + return Webcam.getWebcams(timeout); + } + + private static final WebcamDiscoveryListener webcamDiscoveryListener = new WebcamDiscoveryListener(){ + @Override + public void webcamFound(WebcamDiscoveryEvent event){ + for(Invoker invoker : webcamFoundInvokers){ + invoker.callAny(event); + } + } + + @Override + public void webcamGone(WebcamDiscoveryEvent event){ + for(Invoker invoker : webcamGoneInvokers){ + invoker.callAny(event); + } + } + }; + static{ + Webcam.addDiscoveryListener(webcamDiscoveryListener); + } + + private static final List webcamFoundInvokers = new ArrayList<>(); + private static final List webcamGoneInvokers = new ArrayList<>(); + + @Reflection.Signature + public static WrapInvoker addWebcamFoundListener(Environment env, Invoker handler){ + webcamFoundInvokers.add(handler); + return new WrapInvoker(env, handler); + } + @Reflection.Signature + public static WrapInvoker addWebcamGoneListener(Environment env, Invoker handler){ + webcamGoneInvokers.add(handler); + return new WrapInvoker(env, handler); + } + @Reflection.Signature + public static boolean removeWebcamFoundListener(Invoker handler){ + return webcamFoundInvokers.remove(handler); + } + @Reflection.Signature + public static boolean removeWebcamGoneListener(Invoker handler){ + return webcamGoneInvokers.remove(handler); + } +} diff --git a/src-jvm/main/java/org/develnext/jphp/ext/webcam/classes/event/WebcamDiscoveryEventWrapper.java b/src-jvm/main/java/org/develnext/jphp/ext/webcam/classes/event/WebcamDiscoveryEventWrapper.java new file mode 100644 index 0000000..d5e03b8 --- /dev/null +++ b/src-jvm/main/java/org/develnext/jphp/ext/webcam/classes/event/WebcamDiscoveryEventWrapper.java @@ -0,0 +1,36 @@ +package org.develnext.jphp.ext.webcam.classes.event; + +import com.github.sarxos.webcam.Webcam; +import com.github.sarxos.webcam.WebcamDiscoveryEvent; + +import com.github.sarxos.webcam.WebcamDiscoveryListener; +import org.develnext.jphp.ext.webcam.WebcamExtension; +import php.runtime.annotation.Reflection; +import php.runtime.env.Environment; +import php.runtime.lang.BaseWrapper; +import php.runtime.reflection.ClassEntity; + +@Reflection.Name("WebcamDiscoveryEvent") +@Reflection.Namespace(WebcamExtension.NS+"\\event") +@Reflection.Abstract +public class WebcamDiscoveryEventWrapper extends BaseWrapper { + public WebcamDiscoveryEventWrapper(Environment env, WebcamDiscoveryEvent wrappedObject) { + super(env, wrappedObject); + } + public WebcamDiscoveryEventWrapper(Environment env, ClassEntity clazz) { + super(env, clazz); + } + + interface WrappedInterface{ + @Reflection.Getter Webcam getWebcam(); + } + + @Reflection.Signature + public boolean isAdded(){ + return getWrappedObject().getType() == WebcamDiscoveryEvent.ADDED; + } + @Reflection.Signature + public boolean isRemoved(){ + return getWrappedObject().getType() == WebcamDiscoveryEvent.REMOVED; + } +} diff --git a/src-jvm/main/java/org/develnext/jphp/ext/webcam/classes/event/WebcamMotionEventWrapper.java b/src-jvm/main/java/org/develnext/jphp/ext/webcam/classes/event/WebcamMotionEventWrapper.java new file mode 100644 index 0000000..01f8b46 --- /dev/null +++ b/src-jvm/main/java/org/develnext/jphp/ext/webcam/classes/event/WebcamMotionEventWrapper.java @@ -0,0 +1,80 @@ +package org.develnext.jphp.ext.webcam.classes.event; + +import com.github.sarxos.webcam.Webcam; +import com.github.sarxos.webcam.WebcamMotionEvent; +import javafx.embed.swing.SwingFXUtils; +import javafx.scene.image.Image; +import org.develnext.jphp.ext.webcam.WebcamExtension; +import php.runtime.Memory; +import php.runtime.annotation.Reflection; +import php.runtime.env.Environment; +import php.runtime.lang.BaseWrapper; +import php.runtime.memory.ArrayMemory; +import php.runtime.reflection.ClassEntity; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.lang.reflect.Array; +import java.util.ArrayList; + +@Reflection.Name("WebcamMotionEvent") +@Reflection.Namespace(WebcamExtension.NS+"\\event") +@Reflection.Abstract +public class WebcamMotionEventWrapper extends BaseWrapper { + public WebcamMotionEventWrapper(Environment env, WebcamMotionEvent wrappedObject) { + super(env, wrappedObject); + } + public WebcamMotionEventWrapper(Environment env, ClassEntity clazz) { + super(env, clazz); + } + + interface WrappedInterface{ + @Reflection.Getter Webcam getWebcam(); + @Reflection.Getter double getArea(); + } + + @Reflection.Getter + public Memory getCog(){ + Point cog = getWrappedObject().getCog(); + + ArrayMemory res = new ArrayMemory(); + + res.add(cog.getX()); + res.add(cog.getY()); + + return res; + } + + @Reflection.Getter + public Memory getPoints(){ + ArrayMemory result = new ArrayMemory(); + + ArrayList pointList = getWrappedObject().getPoints(); + if(pointList == null){ + return result; + } + for(Point point : pointList){ + ArrayMemory pointInfo = new ArrayMemory(); + + pointInfo.add(point.getX()); + pointInfo.add(point.getY()); + + result.add(pointInfo); + } + return result; + } + + @Reflection.Getter + public Image getCurrentImage(){ + BufferedImage bufferedImage = getWrappedObject().getCurrentImage(); + + return bufferedImage == null ? null : SwingFXUtils.toFXImage(bufferedImage, null); + } + @Reflection.Getter + public Image getPreviousImage(){ + BufferedImage bufferedImage = getWrappedObject().getPreviousImage(); + + return bufferedImage == null ? null : SwingFXUtils.toFXImage(bufferedImage, null); + } + +} \ No newline at end of file diff --git a/src-jvm/main/java/org/develnext/jphp/ext/webcam/classes/gui/WebcamViewWrapper.java b/src-jvm/main/java/org/develnext/jphp/ext/webcam/classes/gui/WebcamViewWrapper.java new file mode 100644 index 0000000..36b24a0 --- /dev/null +++ b/src-jvm/main/java/org/develnext/jphp/ext/webcam/classes/gui/WebcamViewWrapper.java @@ -0,0 +1,49 @@ +package org.develnext.jphp.ext.webcam.classes.gui; + +import com.github.sarxos.webcam.Webcam; +import javafx.scene.paint.Color; +import javafx.scene.paint.Paint; +import org.develnext.jphp.ext.javafx.classes.UXControl; +import org.develnext.jphp.ext.webcam.support.control.WebcamView; +import php.runtime.annotation.Reflection; +import php.runtime.env.Environment; +import php.runtime.reflection.ClassEntity; + +@Reflection.Name("UXWebcamView") +@Reflection.Namespace("php\\gui") +public class WebcamViewWrapper extends UXControl { + public WebcamViewWrapper(Environment env, WebcamView wrappedObject) { + super(env, wrappedObject); + } + public WebcamViewWrapper(Environment env, ClassEntity clazz) { + super(env, clazz); + } + + interface WrappedInterface{ + void play(); + void stop(); + + @Reflection.Property Webcam webcam(); + + @Reflection.Property WebcamView.WebcamViewMode closeMode(); + @Reflection.Property WebcamView.WebcamViewMode openMode(); + @Reflection.Property boolean stopped(); + @Reflection.Property boolean stretch(); + @Reflection.Property boolean centered(); + @Reflection.Property boolean flipX(); + @Reflection.Property boolean flipY(); + } + @Reflection.Signature + public void __construct(){ + __wrappedObject = new WebcamView(); + } + @Reflection.Getter + public Color getPlaceholderColor(){ + Paint paint = getWrappedObject().getPlaceholderFill(); + return (paint instanceof Color) ? (Color)paint : null; + } + @Reflection.Setter + public void setPlaceholderColor(Color color){ + getWrappedObject().setPlaceholderFill(color); + } +} diff --git a/src-jvm/main/java/org/develnext/jphp/ext/webcam/support/control/WebcamView.java b/src-jvm/main/java/org/develnext/jphp/ext/webcam/support/control/WebcamView.java new file mode 100644 index 0000000..e9d299c --- /dev/null +++ b/src-jvm/main/java/org/develnext/jphp/ext/webcam/support/control/WebcamView.java @@ -0,0 +1,170 @@ +package org.develnext.jphp.ext.webcam.support.control; + +import com.github.sarxos.webcam.Webcam; +import javafx.application.Application; +import javafx.beans.property.*; +import javafx.scene.Scene; +import javafx.scene.control.Control; +import javafx.scene.control.Skin; +import javafx.scene.paint.Color; +import javafx.scene.paint.Paint; +import javafx.stage.Stage; +import org.develnext.jphp.ext.webcam.support.skin.WebcamViewSkin; + +public class WebcamView extends Control{ + + public WebcamView(){ + webcamProperty.addListener((obs, o, n) -> { + + if(o != null){ + switch(getCloseMode()){ + case SYNC: + case ASYNC: + o.close(); + } + } + if(n != null){ + switch(getOpenMode()){ + case SYNC: + n.open(false); + break; + case ASYNC: + n.open(true); + break; + } + } + }); + } + + public final void play(){ + stopped.set(false); + } + public final void stop(){ + stopped.set(true); + } + + + private final ObjectProperty webcamProperty = new SimpleObjectProperty<>(); + + public final void setWebcam(Webcam webcam){ + webcamProperty.set(webcam); + } + public final Webcam getWebcam(){ + return webcamProperty.get(); + } + public final ObjectProperty webcamProperty(){ + return webcamProperty; + } + + + private final ObjectProperty placeholderFillProperty = new SimpleObjectProperty<>(); + + public final void setPlaceholderFill(Paint paint){ + placeholderFillProperty.set(paint); + } + public final Paint getPlaceholderFill(){ + return placeholderFillProperty.get(); + } + public final ObjectProperty placeholderFillProperty(){ + return placeholderFillProperty; + } + + + private final ObjectProperty closeModeProperty = new SimpleObjectProperty<>(WebcamViewMode.NOT_USE); + + public final void setCloseMode(WebcamViewMode value){ + closeModeProperty.set(value); + } + public final WebcamViewMode getCloseMode(){ + return closeModeProperty.get(); + } + public final ObjectProperty closeModeProperty(){ + return closeModeProperty; + } + + + private final ObjectProperty openModeProperty = new SimpleObjectProperty<>(WebcamViewMode.NOT_USE); + + public final void setOpenMode(WebcamViewMode value){ + openModeProperty.set(value); + } + public final WebcamViewMode getOpenMode(){ + return openModeProperty.get(); + } + public final ObjectProperty openModeProperty(){ + return openModeProperty; + } + + + private final ReadOnlyBooleanWrapper stopped = new ReadOnlyBooleanWrapper(true); + + public final boolean isStopped(){ + return stopped.get(); + } + public final ReadOnlyBooleanProperty stoppedProperty(){ + return stopped.getReadOnlyProperty(); + } + + + private final BooleanProperty stretchProperty = new SimpleBooleanProperty(false); + + public final void setStretch(boolean value){ + stretchProperty.set(value); + } + public final boolean isStretch(){ + return stretchProperty.get(); + } + public final BooleanProperty stretchProperty(){ + return stretchProperty; + } + + + private final BooleanProperty centeredProperty = new SimpleBooleanProperty(false); + + public final void setCentered(boolean value){ + centeredProperty.set(value); + } + public final boolean isCentered(){ + return centeredProperty.get(); + } + public final BooleanProperty centeredProperty(){ + return centeredProperty; + } + + private final BooleanProperty flipXProperty = new SimpleBooleanProperty(false); + + public final void setFlipX(boolean value){ + flipXProperty.set(value); + } + public final boolean isFlipX(){ + return flipXProperty.get(); + } + public final BooleanProperty flipXProperty(){ + return flipXProperty; + } + + private final BooleanProperty flipYProperty = new SimpleBooleanProperty(false); + + public final void setFlipY(boolean value){ + flipYProperty.set(value); + } + public final boolean isFlipY(){ + return flipYProperty.get(); + } + public final BooleanProperty flipYProperty(){ + return flipYProperty; + } + + + @Override + protected Skin createDefaultSkin() { + return new WebcamViewSkin(this); + } + + + public enum WebcamViewMode{ + SYNC, + ASYNC, + NOT_USE; + } +} \ No newline at end of file diff --git a/src-jvm/main/java/org/develnext/jphp/ext/webcam/support/memory/WebcamViewModeMemoryOperation.java b/src-jvm/main/java/org/develnext/jphp/ext/webcam/support/memory/WebcamViewModeMemoryOperation.java new file mode 100644 index 0000000..432772d --- /dev/null +++ b/src-jvm/main/java/org/develnext/jphp/ext/webcam/support/memory/WebcamViewModeMemoryOperation.java @@ -0,0 +1,25 @@ +package org.develnext.jphp.ext.webcam.support.memory; + +import org.develnext.jphp.ext.webcam.support.control.WebcamView; +import php.runtime.Memory; +import php.runtime.env.Environment; +import php.runtime.env.TraceInfo; +import php.runtime.memory.StringMemory; +import php.runtime.memory.support.MemoryOperation; + +public class WebcamViewModeMemoryOperation extends MemoryOperation { + @Override + public Class[] getOperationClasses() { + return new Class[]{WebcamView.WebcamViewMode.class}; + } + + @Override + public WebcamView.WebcamViewMode convert(Environment environment, TraceInfo traceInfo, Memory memory) throws Throwable { + return WebcamView.WebcamViewMode.valueOf(memory.toString()); + } + + @Override + public Memory unconvert(Environment environment, TraceInfo traceInfo, WebcamView.WebcamViewMode mode) throws Throwable { + return new StringMemory(mode.toString()); + } +} diff --git a/src-jvm/main/java/org/develnext/jphp/ext/webcam/support/skin/WebcamViewSkin.java b/src-jvm/main/java/org/develnext/jphp/ext/webcam/support/skin/WebcamViewSkin.java new file mode 100644 index 0000000..763f2e8 --- /dev/null +++ b/src-jvm/main/java/org/develnext/jphp/ext/webcam/support/skin/WebcamViewSkin.java @@ -0,0 +1,136 @@ +package org.develnext.jphp.ext.webcam.support.skin; + +import com.github.sarxos.webcam.Webcam; +import javafx.animation.AnimationTimer; +import javafx.application.Application; +import javafx.embed.swing.SwingFXUtils; +import javafx.geometry.BoundingBox; +import javafx.geometry.Bounds; +import javafx.scene.Scene; +import javafx.scene.canvas.Canvas; +import javafx.scene.canvas.GraphicsContext; +import javafx.scene.control.Button; +import javafx.scene.control.SkinBase; +import javafx.scene.control.ToggleButton; +import javafx.scene.effect.BoxBlur; +import javafx.scene.image.Image; +import javafx.scene.layout.*; +import javafx.scene.paint.Color; +import javafx.scene.paint.Paint; +import javafx.stage.Stage; +import org.develnext.jphp.ext.webcam.support.control.WebcamView; + +import java.awt.*; +import java.awt.image.BufferedImage; + +public class WebcamViewSkin extends SkinBase { + private final Canvas canvas; + private final GraphicsContext gc; + private final AnimationTimer timer; + + public WebcamViewSkin(WebcamView view) { + super(view); + canvas = new Canvas(); + gc = canvas.getGraphicsContext2D(); + view.widthProperty().addListener((obs, o, n) -> { + canvas.setWidth(n.doubleValue()); + }); + view.heightProperty().addListener((obs, o, n) -> { + canvas.setHeight(n.doubleValue()); + }); + + + timer = new AnimationTimer(){ + @Override + public void handle(long now){ + if(view.isStopped()){ + fillPlaceholder(); + return; + } + + Webcam webcam = view.webcamProperty().get(); + + if(webcam == null){ + fillPlaceholder(); + return; + } + + BufferedImage bufferedImage = webcam.getImage(); + if(bufferedImage == null){ + fillPlaceholder(); + return; + } + Image image = SwingFXUtils.toFXImage(bufferedImage, null); + gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); + + Bounds bounds = calculateBounds(image.getWidth(), image.getHeight()); + + double w1 = bounds.getWidth(); + double h1 = bounds.getHeight(); + + double x1 = bounds.getMinX(); + double y1 = bounds.getMinY(); + + gc.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), x1, y1, w1, h1); + } + }; + timer.start(); + + getChildren().add(canvas); + } + private Bounds calculateBounds(double sw, double sh){ + return calculateBounds(sw, sh, false); + } + private Bounds calculateBounds(double sw, double sh, boolean forPlaceholder){ + WebcamView view = getSkinnable(); + + + double w = sw; + double h = sh; + double x = 0; + double y = 0; + + if(view.isStretch()){ + w = canvas.getWidth(); + h = canvas.getHeight(); + } + if(!forPlaceholder){ + if(view.isFlipX()){ + x = w; + w = -w; + } + if(view.isFlipY()){ + y = h; + h = -h; + } + } + if(view.isCentered()){ + x = (canvas.getWidth() - w) / 2; + y = (canvas.getHeight() - h) / 2; + } + + return new BoundingBox(x, y, w, h); + } + private void fillPlaceholder(){ + gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); + Paint paint = getSkinnable().getPlaceholderFill(); + if(paint != null){ + double sw; + double sh; + + Dimension dimension = getSkinnable().getWebcam() == null ? null : getSkinnable().getWebcam().getViewSize(); + if(dimension != null){ + sw = dimension.getWidth(); + sh = dimension.getHeight(); + } + else{ + sw = canvas.getWidth(); + sh = canvas.getHeight(); + } + + Bounds bounds = calculateBounds(sw, sh, true); + gc.setFill(paint); + gc.fillRect(bounds.getMinX(), bounds.getMinY(), bounds.getWidth(), bounds.getHeight()); + } + } +} diff --git a/src-jvm/main/resources/META-INF/services/php.runtime.ext.support.Extension b/src-jvm/main/resources/META-INF/services/php.runtime.ext.support.Extension new file mode 100644 index 0000000..0c12ae2 --- /dev/null +++ b/src-jvm/main/resources/META-INF/services/php.runtime.ext.support.Extension @@ -0,0 +1 @@ +org.develnext.jphp.ext.webcam.WebcamExtension \ No newline at end of file