├── app ├── .gitignore ├── src │ └── main │ │ ├── ic_launcher-web.png │ │ ├── res │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ ├── values │ │ │ ├── colors.xml │ │ │ ├── styles.xml │ │ │ └── strings.xml │ │ ├── drawable │ │ │ ├── ic_flash_on.xml │ │ │ ├── ic_flash_off.xml │ │ │ ├── ic_flash_auto.xml │ │ │ ├── ic_flash_torch.xml │ │ │ ├── ic_info.xml │ │ │ ├── ic_facing_back.xml │ │ │ ├── ic_gallery.xml │ │ │ ├── ic_facing.xml │ │ │ ├── ic_facing_front.xml │ │ │ ├── ic_preview.xml │ │ │ ├── ic_photo.xml │ │ │ ├── ic_camera.xml │ │ │ ├── ic_settings.xml │ │ │ ├── video_button.xml │ │ │ ├── logomark_light.xml │ │ │ └── launch_bg.xml │ │ └── menu │ │ │ └── main.xml │ │ └── AndroidManifest.xml ├── build.gradle └── proguard-rules.pro ├── camerakit ├── .gitignore ├── src │ └── main │ │ ├── java │ │ └── com │ │ │ ├── camerakit │ │ │ ├── api │ │ │ │ ├── camera1 │ │ │ │ │ ├── ext │ │ │ │ │ │ ├── Camera.kt │ │ │ │ │ │ └── Parameters.kt │ │ │ │ │ └── Camera1.kt │ │ │ │ ├── CameraApi.kt │ │ │ │ ├── CameraEvents.kt │ │ │ │ ├── CameraAttributes.kt │ │ │ │ ├── CameraHandler.kt │ │ │ │ ├── CameraActions.kt │ │ │ │ ├── camera2 │ │ │ │ │ └── ext │ │ │ │ │ │ ├── CameraDevice.kt │ │ │ │ │ │ ├── CameraManager.kt │ │ │ │ │ │ └── CameraCharacteristics.kt │ │ │ │ └── ManagedCameraApi.kt │ │ │ ├── type │ │ │ │ ├── CameraFacing.kt │ │ │ │ ├── CameraFlash.kt │ │ │ │ └── CameraSize.kt │ │ │ ├── preview │ │ │ │ ├── CameraSurfaceTextureListener.kt │ │ │ │ ├── CameraSurfaceTexture.kt │ │ │ │ └── CameraSurfaceView.kt │ │ │ ├── util │ │ │ │ ├── RawResReader.kt │ │ │ │ └── CameraSizeCalculator.kt │ │ │ └── GestureLayout.java │ │ │ └── wonderkiln │ │ │ └── camerakit │ │ │ ├── CameraConfig.java │ │ │ ├── CameraKitController.java │ │ │ ├── CameraKitHandler.java │ │ │ ├── CameraProperties.java │ │ │ ├── CameraKit.java │ │ │ └── FocusMarkerLayout.java │ │ ├── jniLibs │ │ ├── x86 │ │ │ └── libjpeg-turbo.a │ │ ├── x86_64 │ │ │ └── libjpeg-turbo.a │ │ ├── arm64-v8a │ │ │ └── libjpeg-turbo.a │ │ └── armeabi-v7a │ │ │ └── libjpeg-turbo.a │ │ ├── api21 │ │ └── com │ │ │ └── wonderkiln │ │ │ └── camerakit │ │ │ └── Camera2.java │ │ ├── events │ │ └── com │ │ │ └── wonderkiln │ │ │ └── camerakit │ │ │ ├── CameraKitEventCallback.java │ │ │ ├── CameraKitEventListener.java │ │ │ ├── CameraKitVideo.java │ │ │ ├── OnCameraKitEvent.java │ │ │ ├── CameraKitEventListenerAdapter.java │ │ │ ├── CameraKitImage.java │ │ │ ├── CameraKitError.java │ │ │ ├── CameraKitEvent.java │ │ │ └── EventDispatcher.java │ │ ├── res │ │ ├── drawable │ │ │ ├── focus_marker_fill.xml │ │ │ └── focus_marker_outline.xml │ │ ├── layout │ │ │ ├── texture_view.xml │ │ │ ├── surface_view.xml │ │ │ └── layout_focus_marker.xml │ │ └── values │ │ │ └── attrs.xml │ │ ├── vision │ │ └── com │ │ │ └── wonderkiln │ │ │ └── camerakit │ │ │ ├── GooglePlayServicesUnavailableException.java │ │ │ ├── CameraKitTextDetect.java │ │ │ ├── CameraKitTextBlock.java │ │ │ └── TextProcessor.java │ │ ├── types │ │ └── com │ │ │ └── wonderkiln │ │ │ └── camerakit │ │ │ ├── Facing.java │ │ │ ├── CaptureMethod.java │ │ │ ├── Permissions.java │ │ │ ├── Flash.java │ │ │ ├── Focus.java │ │ │ └── VideoQuality.java │ │ ├── cpp │ │ ├── CMakeLists.txt │ │ ├── main.cpp │ │ ├── libjpeg │ │ │ └── include │ │ │ │ ├── jpegcomp.h │ │ │ │ ├── jversion.h │ │ │ │ ├── jchuff.h │ │ │ │ ├── jconfig.h │ │ │ │ ├── bmp.h │ │ │ │ ├── tjutil.h │ │ │ │ ├── jinclude.h │ │ │ │ ├── config.h │ │ │ │ ├── jsimddct.h │ │ │ │ └── cderror.h │ │ ├── camerakit │ │ │ ├── CameraSurfaceView.hpp │ │ │ └── CameraSurfaceTexture.hpp │ │ ├── jni_camera_surface_texture.cpp │ │ └── jni_camera_surface_view.cpp │ │ ├── CMakeLists.txt │ │ ├── AndroidManifest.xml │ │ ├── utils │ │ └── com │ │ │ └── wonderkiln │ │ │ └── camerakit │ │ │ ├── Size.java │ │ │ ├── Rotation.java │ │ │ ├── YuvOperator.java │ │ │ ├── JpegTransformer.java │ │ │ ├── BitmapOperator.java │ │ │ ├── AspectRatio.java │ │ │ ├── DisplayOrientationDetector.java │ │ │ └── PostProcessor.java │ │ ├── api16 │ │ └── com │ │ │ └── wonderkiln │ │ │ └── camerakit │ │ │ ├── ProcessStillTask.java │ │ │ └── ConstantMapper.java │ │ └── base │ │ └── com │ │ └── wonderkiln │ │ └── camerakit │ │ ├── PreviewImpl.java │ │ ├── CameraImpl.java │ │ ├── CameraViewLayout.java │ │ ├── SurfaceViewContainer.java │ │ └── SurfaceViewPreview.java ├── build.gradle └── deploy.gradle ├── settings.gradle ├── deploy.sh ├── .repo ├── gh-readme-alphaapps-logo.png ├── gh-readme-buddyworks-logo.png ├── gh-join-spectrum.svg └── gh-readme-infitting-logo.svg ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── .gitignore ├── LICENSE ├── .github ├── CONTRIBUTING.md ├── issue-labels.json ├── PULL_REQUEST_TEMPALTE.md ├── TESTING_PROCEDURES.md ├── ISSUE_TEMPLATE.md └── CODE_OF_CONDUCT.md ├── gradlew.bat ├── gradlew └── README.md /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /camerakit/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':camerakit' 2 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./gradlew camerakit:deploySnapshot 4 | 5 | exit 0 6 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/api/camera1/ext/Camera.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.api.camera1.ext 2 | 3 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CameraKit/camerakit-android/HEAD/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /.repo/gh-readme-alphaapps-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CameraKit/camerakit-android/HEAD/.repo/gh-readme-alphaapps-logo.png -------------------------------------------------------------------------------- /.repo/gh-readme-buddyworks-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CameraKit/camerakit-android/HEAD/.repo/gh-readme-buddyworks-logo.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CameraKit/camerakit-android/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536m 2 | kotlin.coroutines=enable 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/wonderkiln/camerakit/CameraConfig.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | public class CameraConfig { 4 | } 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CameraKit/camerakit-android/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CameraKit/camerakit-android/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CameraKit/camerakit-android/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CameraKit/camerakit-android/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CameraKit/camerakit-android/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/type/CameraFacing.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.type 2 | 3 | enum class CameraFacing { 4 | BACK, 5 | FRONT; 6 | } -------------------------------------------------------------------------------- /camerakit/src/main/jniLibs/x86/libjpeg-turbo.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CameraKit/camerakit-android/HEAD/camerakit/src/main/jniLibs/x86/libjpeg-turbo.a -------------------------------------------------------------------------------- /camerakit/src/main/java/com/wonderkiln/camerakit/CameraKitController.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | public class CameraKitController { 4 | } 5 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/wonderkiln/camerakit/CameraKitHandler.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | 4 | public class CameraKitHandler { 5 | } 6 | -------------------------------------------------------------------------------- /camerakit/src/main/jniLibs/x86_64/libjpeg-turbo.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CameraKit/camerakit-android/HEAD/camerakit/src/main/jniLibs/x86_64/libjpeg-turbo.a -------------------------------------------------------------------------------- /camerakit/src/main/jniLibs/arm64-v8a/libjpeg-turbo.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CameraKit/camerakit-android/HEAD/camerakit/src/main/jniLibs/arm64-v8a/libjpeg-turbo.a -------------------------------------------------------------------------------- /camerakit/src/main/jniLibs/armeabi-v7a/libjpeg-turbo.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CameraKit/camerakit-android/HEAD/camerakit/src/main/jniLibs/armeabi-v7a/libjpeg-turbo.a -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/type/CameraFlash.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.type 2 | 3 | enum class CameraFlash { 4 | OFF, 5 | ON, 6 | AUTO, 7 | TORCH; 8 | } -------------------------------------------------------------------------------- /camerakit/src/main/api21/com/wonderkiln/camerakit/Camera2.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.annotation.TargetApi; 4 | 5 | @TargetApi(21) 6 | class Camera2 { 7 | } 8 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/api/CameraApi.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.api 2 | 3 | interface CameraApi : CameraActions, CameraEvents { 4 | 5 | val cameraHandler: CameraHandler 6 | 7 | } -------------------------------------------------------------------------------- /camerakit/src/main/events/com/wonderkiln/camerakit/CameraKitEventCallback.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | public interface CameraKitEventCallback { 4 | void callback(T event); 5 | } 6 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/preview/CameraSurfaceTextureListener.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.preview 2 | 3 | interface CameraSurfaceTextureListener { 4 | fun onSurfaceReady(cameraSurfaceTexture: CameraSurfaceTexture) 5 | } 6 | -------------------------------------------------------------------------------- /camerakit/src/main/res/drawable/focus_marker_fill.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Jun 27 13:12:11 EDT 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip 7 | -------------------------------------------------------------------------------- /camerakit/src/main/res/drawable/focus_marker_outline.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #37474F 4 | #263238 5 | #131B1F 6 | #F44336 7 | 8 | -------------------------------------------------------------------------------- /camerakit/src/main/events/com/wonderkiln/camerakit/CameraKitEventListener.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | public interface CameraKitEventListener { 4 | void onEvent(CameraKitEvent event); 5 | void onError(CameraKitError error); 6 | void onImage(CameraKitImage image); 7 | void onVideo(CameraKitVideo video); 8 | } -------------------------------------------------------------------------------- /camerakit/src/main/res/layout/texture_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/api/CameraEvents.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.api 2 | 3 | interface CameraEvents { 4 | 5 | fun onCameraOpened(cameraAttributes: CameraAttributes) 6 | fun onCameraClosed() 7 | fun onCameraError() 8 | 9 | fun onPreviewStarted() 10 | fun onPreviewStopped() 11 | fun onPreviewError() 12 | 13 | } -------------------------------------------------------------------------------- /camerakit/src/main/vision/com/wonderkiln/camerakit/GooglePlayServicesUnavailableException.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | public class GooglePlayServicesUnavailableException extends Exception { 4 | public GooglePlayServicesUnavailableException() { 5 | super("Could not start text detection - Google Play Services Unavailable."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_flash_on.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_flash_off.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_flash_auto.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/util/RawResReader.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.util 2 | 3 | import android.content.Context 4 | import androidx.annotation.RawRes 5 | 6 | class RawResReader(context: Context, @RawRes resId: Int) { 7 | 8 | val value: String 9 | 10 | init { 11 | val inputStream = context.resources.openRawResource(resId) 12 | value = inputStream.bufferedReader().use { it.readText() } 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_flash_torch.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/api/CameraAttributes.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.api 2 | 3 | import com.camerakit.type.CameraFacing 4 | import com.camerakit.type.CameraFlash 5 | import com.camerakit.type.CameraSize 6 | 7 | interface CameraAttributes { 8 | 9 | val facing: CameraFacing 10 | val sensorOrientation: Int 11 | val previewSizes: Array 12 | val photoSizes: Array 13 | val flashes: Array 14 | 15 | } -------------------------------------------------------------------------------- /camerakit/src/main/events/com/wonderkiln/camerakit/CameraKitVideo.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import java.io.File; 4 | 5 | public class CameraKitVideo extends CameraKitEvent { 6 | 7 | private File videoFile; 8 | 9 | CameraKitVideo(File videoFile) { 10 | super(TYPE_VIDEO_CAPTURED); 11 | this.videoFile = videoFile; 12 | } 13 | 14 | public File getVideoFile() { 15 | return videoFile; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/wonderkiln/camerakit/CameraProperties.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | public class CameraProperties { 4 | public final float verticalViewingAngle; 5 | public final float horizontalViewingAngle; 6 | 7 | public CameraProperties(float verticalViewingAngle, float horizontalViewingAngle) { 8 | this.verticalViewingAngle = verticalViewingAngle; 9 | this.horizontalViewingAngle = horizontalViewingAngle; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /camerakit/src/main/events/com/wonderkiln/camerakit/OnCameraKitEvent.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target(ElementType.METHOD) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | public @interface OnCameraKitEvent { 11 | Class value() default CameraKitEvent.class; 12 | } 13 | -------------------------------------------------------------------------------- /camerakit/src/main/vision/com/wonderkiln/camerakit/CameraKitTextDetect.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | public class CameraKitTextDetect extends CameraKitEvent { 4 | 5 | private CameraKitTextBlock textBlock; 6 | 7 | public CameraKitTextDetect(CameraKitTextBlock textBlock) { 8 | super(TYPE_TEXT_DETECTED); 9 | this.textBlock = textBlock; 10 | } 11 | 12 | public CameraKitTextBlock getTextBlock() { 13 | return textBlock; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /camerakit/src/main/types/com/wonderkiln/camerakit/Facing.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.support.annotation.IntDef; 4 | 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | 8 | import static com.wonderkiln.camerakit.CameraKit.Constants.FACING_BACK; 9 | import static com.wonderkiln.camerakit.CameraKit.Constants.FACING_FRONT; 10 | 11 | @IntDef({FACING_BACK, FACING_FRONT}) 12 | @Retention(RetentionPolicy.SOURCE) 13 | public @interface Facing { 14 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_info.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_facing_back.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_gallery.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_facing.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /camerakit/src/main/types/com/wonderkiln/camerakit/CaptureMethod.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.support.annotation.IntDef; 4 | 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | 8 | import static com.wonderkiln.camerakit.CameraKit.Constants.METHOD_STANDARD; 9 | import static com.wonderkiln.camerakit.CameraKit.Constants.METHOD_STILL; 10 | 11 | @Retention(RetentionPolicy.SOURCE) 12 | @IntDef({METHOD_STANDARD, METHOD_STILL}) 13 | public @interface CaptureMethod { 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 9 | 14 | -------------------------------------------------------------------------------- /camerakit/src/main/events/com/wonderkiln/camerakit/CameraKitEventListenerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | public abstract class CameraKitEventListenerAdapter implements CameraKitEventListener { 4 | 5 | @Override 6 | public void onEvent(CameraKitEvent event) { 7 | } 8 | 9 | @Override 10 | public void onError(CameraKitError error) { 11 | } 12 | 13 | @Override 14 | public void onImage(CameraKitImage image) { 15 | } 16 | 17 | @Override 18 | public void onVideo(CameraKitVideo video) { 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_facing_front.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /camerakit/src/main/events/com/wonderkiln/camerakit/CameraKitImage.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.BitmapFactory; 5 | 6 | public class CameraKitImage extends CameraKitEvent { 7 | 8 | private byte[] jpeg; 9 | 10 | CameraKitImage(byte[] jpeg) { 11 | super(TYPE_IMAGE_CAPTURED); 12 | this.jpeg = jpeg; 13 | } 14 | 15 | public byte[] getJpeg() { 16 | return jpeg; 17 | } 18 | 19 | public Bitmap getBitmap() { 20 | return BitmapFactory.decodeByteArray(jpeg, 0, jpeg.length); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_preview.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /camerakit/src/main/events/com/wonderkiln/camerakit/CameraKitError.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.support.annotation.Nullable; 4 | 5 | public class CameraKitError extends CameraKitEvent { 6 | 7 | private String type; 8 | private String message; 9 | private Exception exception; 10 | 11 | CameraKitError() { 12 | super(TYPE_ERROR); 13 | } 14 | 15 | CameraKitError(Exception exception) { 16 | super(TYPE_ERROR); 17 | this.exception = exception; 18 | } 19 | 20 | @Nullable 21 | public Exception getException() { 22 | return exception; 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /camerakit/src/main/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.4.1) 2 | set(CMAKE_CXX_STANDARD 14) 3 | 4 | add_library(camerakit-core SHARED 5 | camerakit/CameraSurfaceTexture.cpp 6 | camerakit/CameraSurfaceTexture.hpp 7 | camerakit/CameraSurfaceView.cpp 8 | camerakit/CameraSurfaceView.hpp) 9 | 10 | target_link_libraries(camerakit-core 11 | PUBLIC -llog 12 | PUBLIC -lGLESv2) 13 | 14 | add_library(camerakit SHARED 15 | jni_camera_surface_texture.cpp 16 | jni_camera_surface_view.cpp 17 | main.cpp) 18 | 19 | target_link_libraries(camerakit 20 | PUBLIC camerakit-core) 21 | -------------------------------------------------------------------------------- /camerakit/src/main/cpp/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | 5 | #include 6 | 7 | namespace camerakit { 8 | namespace jni { 9 | extern int register_CameraSurfaceView(JNIEnv* env); 10 | extern int register_CameraSurfaceTexture(JNIEnv* env); 11 | } 12 | } 13 | 14 | using namespace camerakit; 15 | 16 | JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { 17 | JNIEnv* env; 18 | if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { 19 | return -1; 20 | } 21 | 22 | jni::register_CameraSurfaceView(env); 23 | jni::register_CameraSurfaceTexture(env); 24 | return JNI_VERSION_1_6; 25 | } 26 | -------------------------------------------------------------------------------- /camerakit/src/main/types/com/wonderkiln/camerakit/Permissions.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.support.annotation.IntDef; 4 | 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | 8 | import static com.wonderkiln.camerakit.CameraKit.Constants.PERMISSIONS_LAZY; 9 | import static com.wonderkiln.camerakit.CameraKit.Constants.PERMISSIONS_PICTURE; 10 | import static com.wonderkiln.camerakit.CameraKit.Constants.PERMISSIONS_STRICT; 11 | 12 | @Retention(RetentionPolicy.SOURCE) 13 | @IntDef({PERMISSIONS_STRICT, PERMISSIONS_LAZY, PERMISSIONS_PICTURE}) 14 | public @interface Permissions { 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_photo.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/api/CameraHandler.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.api 2 | 3 | import android.os.Handler 4 | import android.os.HandlerThread 5 | 6 | class CameraHandler private constructor(thread: HandlerThread) : Handler(thread.looper) { 7 | 8 | companion object { 9 | fun get(): CameraHandler { 10 | val cameraThread = HandlerThread("CameraHandler@${System.currentTimeMillis()}") 11 | cameraThread.start() 12 | return CameraHandler(cameraThread) 13 | } 14 | } 15 | 16 | init { 17 | thread.setUncaughtExceptionHandler { thread, exception -> 18 | } 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /camerakit/src/main/res/layout/surface_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /camerakit/src/main/types/com/wonderkiln/camerakit/Flash.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.support.annotation.IntDef; 4 | 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | 8 | import static com.wonderkiln.camerakit.CameraKit.Constants.FLASH_AUTO; 9 | import static com.wonderkiln.camerakit.CameraKit.Constants.FLASH_OFF; 10 | import static com.wonderkiln.camerakit.CameraKit.Constants.FLASH_ON; 11 | import static com.wonderkiln.camerakit.CameraKit.Constants.FLASH_TORCH; 12 | 13 | @Retention(RetentionPolicy.SOURCE) 14 | @IntDef({FLASH_OFF, FLASH_ON, FLASH_AUTO, FLASH_TORCH}) 15 | public @interface Flash { 16 | } -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'kotlin-android' 4 | } 5 | 6 | android { 7 | compileSdkVersion = versions.compileSdk 8 | defaultConfig { 9 | applicationId 'com.camerakit.app' 10 | minSdkVersion versions.minSdk 11 | targetSdkVersion versions.targetSdk 12 | versionName version 13 | versionCode 1 14 | } 15 | } 16 | 17 | dependencies { 18 | implementation project(':camerakit') 19 | implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.0' 20 | implementation 'androidx.appcompat:appcompat:1.0.2' 21 | implementation 'com.google.android.material:material:1.1.0-alpha02' 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/api/CameraActions.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.api 2 | 3 | import android.graphics.SurfaceTexture 4 | import com.camerakit.type.CameraFacing 5 | import com.camerakit.type.CameraFlash 6 | import com.camerakit.type.CameraSize 7 | 8 | interface CameraActions { 9 | 10 | fun open(facing: CameraFacing) 11 | fun release() 12 | 13 | fun setPreviewOrientation(degrees: Int) 14 | fun setPreviewSize(size: CameraSize) 15 | fun startPreview(surfaceTexture: SurfaceTexture) 16 | fun stopPreview() 17 | 18 | fun setFlash(flash: CameraFlash) 19 | fun setPhotoSize(size: CameraSize) 20 | fun capturePhoto(callback: (jpeg: ByteArray) -> Unit) 21 | 22 | 23 | } -------------------------------------------------------------------------------- /camerakit/src/main/types/com/wonderkiln/camerakit/Focus.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.support.annotation.IntDef; 4 | 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | 8 | import static com.wonderkiln.camerakit.CameraKit.Constants.FOCUS_TAP; 9 | import static com.wonderkiln.camerakit.CameraKit.Constants.FOCUS_OFF; 10 | import static com.wonderkiln.camerakit.CameraKit.Constants.FOCUS_CONTINUOUS; 11 | import static com.wonderkiln.camerakit.CameraKit.Constants.FOCUS_TAP_WITH_MARKER; 12 | 13 | @Retention(RetentionPolicy.SOURCE) 14 | @IntDef({FOCUS_CONTINUOUS, FOCUS_TAP, FOCUS_OFF, FOCUS_TAP_WITH_MARKER}) 15 | public @interface Focus { 16 | } -------------------------------------------------------------------------------- /camerakit/src/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.4.1) 2 | 3 | set(JPEG_INC_DIR ${CMAKE_SOURCE_DIR}/cpp/libjpeg/include) 4 | set(JPEG_BUILD_DIR ${CMAKE_SOURCE_DIR}/jniLibs) 5 | 6 | include_directories(${JPEG_INC_DIR}) 7 | 8 | add_library(libjpeg STATIC IMPORTED) 9 | set_target_properties(libjpeg PROPERTIES IMPORTED_LOCATION ${JPEG_BUILD_DIR}/${ANDROID_ABI}/libjpeg-turbo.a) 10 | 11 | add_library(jpegTransformer SHARED ${CMAKE_SOURCE_DIR}/cpp/JniJpegTransformer.cpp) 12 | add_library(yuvOperator SHARED ${CMAKE_SOURCE_DIR}/cpp/JniYuvOperator.cpp) 13 | 14 | find_library(log-lib log) 15 | find_library(jnigraphics-lib jnigraphics) 16 | 17 | target_link_libraries(jpegTransformer yuvOperator libjpeg ${log-lib} ${jnigraphics-lib}) 18 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/type/CameraSize.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.type 2 | 3 | data class CameraSize(val width: Int, val height: Int) : Comparable { 4 | 5 | fun area(): Int { 6 | return width * height 7 | } 8 | 9 | fun aspectRatio(): Float { 10 | if (width == 0 || height == 0) { 11 | return 1f 12 | } 13 | 14 | return width.toFloat() / height.toFloat() 15 | } 16 | 17 | override fun compareTo(other: CameraSize): Int { 18 | val areaDiff = width * height - other.width * other.height 19 | if (areaDiff > 0) { 20 | return 1 21 | } else if (areaDiff < 0) { 22 | return -1 23 | } else { 24 | return 0 25 | } 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_camera.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /camerakit/src/main/vision/com/wonderkiln/camerakit/CameraKitTextBlock.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.graphics.Point; 4 | import android.graphics.Rect; 5 | 6 | import com.google.android.gms.vision.text.TextBlock; 7 | 8 | public class CameraKitTextBlock { 9 | 10 | private TextBlock textBlock; 11 | 12 | CameraKitTextBlock(TextBlock textBlock) { 13 | this.textBlock = textBlock; 14 | } 15 | 16 | public String getText() { 17 | return textBlock.getValue(); 18 | } 19 | 20 | public Rect getBoundingBox() { 21 | return textBlock.getBoundingBox(); 22 | } 23 | 24 | public Point[] getCornerPoints() { 25 | return textBlock.getCornerPoints(); 26 | } 27 | 28 | public String getLanguage() { 29 | return textBlock.getLanguage(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | .idea/workspace.xml 38 | 39 | # Eclipse 40 | *.project 41 | *.classpath 42 | *.prefs 43 | 44 | # Keystore files 45 | *.jks 46 | 47 | # External native build folder generated in Android Studio 2.2 and later 48 | .externalNativeBuild 49 | 50 | .idea 51 | .DS_Store 52 | 53 | -------------------------------------------------------------------------------- /camerakit/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 14 | 17 | 20 | 21 | -------------------------------------------------------------------------------- /camerakit/src/main/res/layout/layout_focus_marker.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | 16 | 17 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | CameraKit 3 | https://github.com/wonderkiln/camerakit-android 4 | http://camerakit.website 5 | 6 | About 7 | CameraKit is open source software distributed under the MIT license.\n\nFor more details visit www.camerakit.website/. 8 | 9 | Open Drawer 10 | Close Drawer 11 | 12 | 13 | highest 14 | lowest 15 | max480p 16 | max720p 17 | max1080p 18 | max1440p 19 | max2160p 20 | max4320p 21 | 22 | 23 | -------------------------------------------------------------------------------- /camerakit/src/main/cpp/libjpeg/include/jpegcomp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jpegcomp.h 3 | * 4 | * Copyright (C) 2010, D. R. Commander 5 | * For conditions of distribution and use, see the accompanying README file. 6 | * 7 | * JPEG compatibility macros 8 | * These declarations are considered internal to the JPEG library; most 9 | * applications using the library shouldn't need to include this file. 10 | */ 11 | 12 | #if JPEG_LIB_VERSION >= 70 13 | #define _DCT_scaled_size DCT_h_scaled_size 14 | #define _min_DCT_scaled_size min_DCT_h_scaled_size 15 | #define _min_DCT_h_scaled_size min_DCT_h_scaled_size 16 | #define _min_DCT_v_scaled_size min_DCT_v_scaled_size 17 | #define _jpeg_width jpeg_width 18 | #define _jpeg_height jpeg_height 19 | #else 20 | #define _DCT_scaled_size DCT_scaled_size 21 | #define _min_DCT_scaled_size min_DCT_scaled_size 22 | #define _min_DCT_h_scaled_size min_DCT_scaled_size 23 | #define _min_DCT_v_scaled_size min_DCT_scaled_size 24 | #define _jpeg_width image_width 25 | #define _jpeg_height image_height 26 | #endif 27 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/dylanmcintyre/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2018 CameraKit (https://camerakit.website) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /camerakit/src/main/types/com/wonderkiln/camerakit/VideoQuality.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.support.annotation.IntDef; 4 | 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | 8 | import static com.wonderkiln.camerakit.CameraKit.Constants.VIDEO_QUALITY_1080P; 9 | import static com.wonderkiln.camerakit.CameraKit.Constants.VIDEO_QUALITY_2160P; 10 | import static com.wonderkiln.camerakit.CameraKit.Constants.VIDEO_QUALITY_480P; 11 | import static com.wonderkiln.camerakit.CameraKit.Constants.VIDEO_QUALITY_720P; 12 | import static com.wonderkiln.camerakit.CameraKit.Constants.VIDEO_QUALITY_HIGHEST; 13 | import static com.wonderkiln.camerakit.CameraKit.Constants.VIDEO_QUALITY_LOWEST; 14 | import static com.wonderkiln.camerakit.CameraKit.Constants.VIDEO_QUALITY_QVGA; 15 | 16 | @Retention(RetentionPolicy.SOURCE) 17 | @IntDef({VIDEO_QUALITY_QVGA, VIDEO_QUALITY_480P, VIDEO_QUALITY_720P, VIDEO_QUALITY_1080P, VIDEO_QUALITY_2160P, VIDEO_QUALITY_HIGHEST, VIDEO_QUALITY_LOWEST}) 18 | public @interface VideoQuality { 19 | } 20 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We love pull requests from everyone. By participating in this project, you 4 | agree to abide by the CameraKit [code of conduct]. 5 | 6 | [code of conduct]: CODE-OF-CONDUCT.md 7 | 8 | Fork, then clone the repo: 9 | 10 | git clone https://github.com/CameraKit/camerakit-android 11 | 12 | Make your change. Add tests for your change. Make the tests pass. 13 | 14 | Push to your fork and [submit a pull request][pr]. 15 | 16 | [pr]: https://github.com/CameraKit/camerakit-android/pulls 17 | 18 | At this point you're waiting on us. We like to at least comment on pull requests 19 | within three business days (and, typically, one business day). We may suggest 20 | some changes or improvements or alternatives. 21 | 22 | Some things that will increase the chance that your pull request is accepted: 23 | 24 | * Write tests. 25 | * Follow our [style guide][style]. 26 | * Write a [good commit message][commit]. 27 | 28 | [style]: TBD: https://google.github.io/styleguide/javaguide.html 29 | [commit]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html 30 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/api/camera2/ext/CameraDevice.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.api.camera2.ext 2 | 3 | import android.hardware.camera2.CameraCaptureSession 4 | import android.hardware.camera2.CameraDevice 5 | import android.media.ImageReader 6 | import android.os.Handler 7 | import androidx.annotation.RequiresApi 8 | import android.util.Log 9 | import android.view.Surface 10 | 11 | @RequiresApi(21) 12 | fun CameraDevice.getCaptureSession(surface: Surface, imageReader: ImageReader, handler: Handler, callback: (captureSession: CameraCaptureSession?) -> Unit) { 13 | createCaptureSession(listOf(surface, imageReader.surface), object: CameraCaptureSession.StateCallback() { 14 | override fun onConfigured(captureSession: CameraCaptureSession) { 15 | callback(captureSession) 16 | } 17 | 18 | override fun onClosed(session: CameraCaptureSession) { 19 | callback(null) 20 | super.onClosed(session) 21 | } 22 | 23 | override fun onConfigureFailed(captureSession: CameraCaptureSession) { 24 | callback(null) 25 | } 26 | }, handler) 27 | } 28 | -------------------------------------------------------------------------------- /camerakit/src/main/cpp/libjpeg/include/jversion.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jversion.h 3 | * 4 | * Copyright (C) 1991-2010, Thomas G. Lane, Guido Vollbeding. 5 | * Copyright (C) 2010, D. R. Commander. 6 | * This file is part of the Independent JPEG Group's software. 7 | * For conditions of distribution and use, see the accompanying README file. 8 | * 9 | * This file contains software version identification. 10 | */ 11 | 12 | 13 | #if JPEG_LIB_VERSION >= 80 14 | 15 | #define JVERSION "8b 16-May-2010" 16 | 17 | #define JCOPYRIGHT "Copyright (C) 2010, Thomas G. Lane, Guido Vollbeding" 18 | 19 | #elif JPEG_LIB_VERSION >= 70 20 | 21 | #define JVERSION "7 27-Jun-2009" 22 | 23 | #define JCOPYRIGHT "Copyright (C) 2009, Thomas G. Lane, Guido Vollbeding" 24 | 25 | #else 26 | 27 | #define JVERSION "6b 27-Mar-1998" 28 | 29 | #define JCOPYRIGHT "Copyright (C) 1998, Thomas G. Lane" 30 | 31 | #endif 32 | 33 | #define LJTCOPYRIGHT "Copyright (C) 1999-2006 MIYASAKA Masaru\n" \ 34 | "Copyright (C) 2009 Pierre Ossman for Cendio AB\n" \ 35 | "Copyright (C) 2009-2011 D. R. Commander\n" \ 36 | "Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)" 37 | -------------------------------------------------------------------------------- /.github/issue-labels.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "name": "CLA: Signed", "color": "#009800" }, 3 | { "name": "CLA: Unsigned", "color": "#e11d21" }, 4 | { "name": "Priority: Low", "color": "#009800" }, 5 | { "name": "Priority: Medium", "color": "#fbca04" }, 6 | { "name": "Priority: High", "color": "#eb6420" }, 7 | { "name": "Priority: Critical", "color": "#e11d21" }, 8 | { "name": "Status: Abandoned", "color": "#000000" }, 9 | { "name": "Status: Accepted", "color": "#009800" }, 10 | { "name": "Status: Available", "color": "#bfe5bf" }, 11 | { "name": "Status: Blocked", "color": "#e11d21" }, 12 | { "name": "Status: Completed", "color": "#006b75" }, 13 | { "name": "Status: In Progress", "color": "#cccccc" }, 14 | { "name": "Status: On Hold", "color": "#e11d21" }, 15 | { "name": "Status: Pending", "color": "#fef2c0" }, 16 | { "name": "Status: Review Needed", "color": "#fbca04" }, 17 | { "name": "Status: Revision Needed", "color": "#e11d21" }, 18 | { "name": "Type: Bug", "color": "#e11d21" }, 19 | { "name": "Type: Maintenance", "color": "#fbca04" }, 20 | { "name": "Type: Enhancement", "color": "#84b6eb" }, 21 | { "name": "Type: Question", "color": "#cc317c" } 22 | ] 23 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/util/CameraSizeCalculator.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.util 2 | 3 | import com.camerakit.type.CameraSize 4 | import kotlin.math.absoluteValue 5 | 6 | class CameraSizeCalculator(private val sizes: Array) { 7 | 8 | fun findClosestSizeContainingTarget(target: CameraSize): CameraSize { 9 | sizes.sort() 10 | 11 | var bestSize = sizes.last() 12 | var bestArea = Int.MAX_VALUE 13 | sizes.forEach { 14 | if (it.width >= target.width 15 | && it.height >= target.height 16 | && it.area() < bestArea) { 17 | bestSize = it 18 | bestArea = it.area() 19 | } 20 | } 21 | 22 | return bestSize 23 | } 24 | 25 | fun findClosestSizeMatchingArea(area: Int): CameraSize { 26 | sizes.sort() 27 | 28 | var bestSize = sizes.last() 29 | sizes.forEach { 30 | if ((area - it.area()).absoluteValue 31 | < (area - bestSize.area()).absoluteValue) { 32 | bestSize = it 33 | } 34 | } 35 | 36 | return bestSize 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/video_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /camerakit/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.library' 3 | id 'kotlin-android' 4 | id 'com.github.dcendents.android-maven' version '1.5' 5 | } 6 | 7 | android { 8 | compileSdkVersion versions.compileSdk 9 | defaultConfig { 10 | minSdkVersion versions.minSdk 11 | externalNativeBuild { 12 | cmake { 13 | cppFlags '-std=c++11' 14 | } 15 | } 16 | } 17 | externalNativeBuild { 18 | cmake { 19 | path 'src/main/cpp/CMakeLists.txt' 20 | } 21 | } 22 | testOptions { 23 | unitTests.returnDefaultValues = true 24 | } 25 | } 26 | 27 | dependencies { 28 | api 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.0' 29 | implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.0' 30 | api 'androidx.annotation:annotation:1.0.1' 31 | api 'com.camerakit:jpegkit:0.2.2' 32 | testImplementation 'junit:junit:4.12' 33 | testImplementation 'org.mockito:mockito-core:1.10.19' 34 | } 35 | 36 | install { 37 | repositories.mavenInstaller { 38 | pom.project { 39 | groupId project.group 40 | artifactId 'camerakit' 41 | packaging 'aar' 42 | } 43 | } 44 | } 45 | 46 | apply from : 'deploy.gradle' 47 | -------------------------------------------------------------------------------- /camerakit/src/main/vision/com/wonderkiln/camerakit/TextProcessor.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.util.SparseArray; 4 | 5 | import com.google.android.gms.vision.Detector; 6 | import com.google.android.gms.vision.text.TextBlock; 7 | 8 | public class TextProcessor implements Detector.Processor { 9 | 10 | private EventDispatcher mEventDispatcher; 11 | private CameraKitEventCallback callback; 12 | 13 | public TextProcessor(EventDispatcher mEventDispatcher, CameraKitEventCallback callback) { 14 | this.mEventDispatcher = mEventDispatcher; 15 | this.callback = callback; 16 | } 17 | 18 | @Override 19 | public void release() { 20 | } 21 | 22 | @Override 23 | public void receiveDetections(Detector.Detections detections) { 24 | 25 | SparseArray detectedItems = detections.getDetectedItems(); 26 | for (int i = 0; i < detectedItems.size(); ++i) { 27 | TextBlock item = detectedItems.valueAt(i); 28 | if (item != null && item.getValue() != null) { 29 | CameraKitTextDetect event = new CameraKitTextDetect(new CameraKitTextBlock(item)); 30 | mEventDispatcher.dispatch(event); 31 | callback.callback(event); 32 | } 33 | } 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /camerakit/src/main/utils/com/wonderkiln/camerakit/Size.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.support.annotation.NonNull; 4 | 5 | public class Size implements Comparable { 6 | 7 | private final int mWidth; 8 | private final int mHeight; 9 | 10 | public Size(int width, int height) { 11 | mWidth = width; 12 | mHeight = height; 13 | } 14 | 15 | public int getWidth() { 16 | return mWidth; 17 | } 18 | 19 | public int getHeight() { 20 | return mHeight; 21 | } 22 | 23 | @Override 24 | public boolean equals(Object o) { 25 | if (o == null) { 26 | return false; 27 | } 28 | if (this == o) { 29 | return true; 30 | } 31 | if (o instanceof Size) { 32 | Size size = (Size) o; 33 | return mWidth == size.mWidth && mHeight == size.mHeight; 34 | } 35 | return false; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return mWidth + "x" + mHeight; 41 | } 42 | 43 | @Override 44 | public int hashCode() { 45 | return mHeight ^ ((mWidth << (Integer.SIZE / 2)) | (mWidth >>> (Integer.SIZE / 2))); 46 | } 47 | 48 | @Override 49 | public int compareTo(@NonNull Size another) { 50 | return mWidth * mHeight - another.mWidth * another.mHeight; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /camerakit/src/main/cpp/camerakit/CameraSurfaceView.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CameraSurfaceTexture.hpp" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #define LOG_TAG "CameraSurfaceView" 13 | #define LOG_DEBUG(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) 14 | #define LOG_ERROR(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) 15 | 16 | namespace camerakit { 17 | 18 | class CameraSurfaceView { 19 | 20 | public: 21 | CameraSurfaceView(); 22 | virtual ~CameraSurfaceView(); 23 | 24 | public: 25 | void onSurfaceCreated(); 26 | void onSurfaceChanged(int width, int height); 27 | void onDrawFrame(); 28 | void drawTexture(GLuint texture, int textureWidth, int textureHeight); 29 | void abandon(); 30 | 31 | private: 32 | int surfaceWidth; 33 | int surfaceHeight; 34 | 35 | GLuint vertexBuffer; 36 | GLuint program; 37 | GLint aPosition; 38 | GLint aTexCoord; 39 | 40 | private: 41 | static const GLfloat* VertexData(); 42 | static const GLushort* VertexIndices(); 43 | 44 | static const char* VertexShaderCode(); 45 | static const char* FragmentShaderCode(); 46 | 47 | static GLuint LoadShader(GLenum shaderType, const char* shaderCode); 48 | static GLuint CreateProgram(const char* vertexShaderCode, const char* fragmentShaderCode); 49 | 50 | }; 51 | 52 | } 53 | -------------------------------------------------------------------------------- /camerakit/src/main/cpp/camerakit/CameraSurfaceTexture.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #define LOG_TAG "CameraSurfaceTexture" 10 | #define LOG_DEBUG(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) 11 | #define LOG_ERROR(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) 12 | 13 | namespace camerakit { 14 | 15 | class CameraSurfaceTexture { 16 | 17 | public: 18 | CameraSurfaceTexture(GLuint inputTexture, GLuint outputTexture); 19 | virtual ~CameraSurfaceTexture(); 20 | 21 | public: 22 | void setSize(int width, int height); 23 | void updateTexImage(float* transformMatrix, float* rotationMatrix); 24 | 25 | private: 26 | int width; 27 | int height; 28 | 29 | GLuint inputTexture; 30 | GLuint outputTexture; 31 | GLuint framebuffer; 32 | GLuint vertexBuffer; 33 | 34 | GLuint program; 35 | GLint aPosition; 36 | GLint aTexCoord; 37 | GLint uTransformMatrix; 38 | GLint uRotationMatrix; 39 | 40 | private: 41 | static const GLfloat* VertexData(); 42 | static const GLushort* VertexIndices(); 43 | 44 | static const char* VertexShaderCode(); 45 | static const char* FragmentShaderCode(); 46 | 47 | static GLuint LoadShader(GLenum shaderType, const char* shaderCode); 48 | static GLuint CreateProgram(const char* vertexShaderCode, const char* fragmentShaderCode); 49 | 50 | }; 51 | 52 | } 53 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/api/camera2/ext/CameraManager.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.api.camera2.ext 2 | 3 | import android.hardware.camera2.CameraCharacteristics 4 | import android.hardware.camera2.CameraManager 5 | import android.os.Handler 6 | import androidx.annotation.RequiresApi 7 | import com.camerakit.type.CameraFacing 8 | 9 | @RequiresApi(21) 10 | fun CameraManager.getCameraId(facing: CameraFacing): String? { 11 | val targetFacingCharacteristic = when (facing) { 12 | CameraFacing.BACK -> CameraCharacteristics.LENS_FACING_BACK 13 | CameraFacing.FRONT -> CameraCharacteristics.LENS_FACING_FRONT 14 | } 15 | 16 | return cameraIdList.find { cameraId -> 17 | val characteristics = getCameraCharacteristics(cameraId) 18 | val facingCharacteristic = characteristics.get(CameraCharacteristics.LENS_FACING) 19 | facingCharacteristic == targetFacingCharacteristic 20 | } 21 | } 22 | 23 | @RequiresApi(21) 24 | fun CameraManager.whenDeviceAvailable(targetCameraId: String, handler: Handler, callback: () -> Unit) { 25 | registerAvailabilityCallback(object : CameraManager.AvailabilityCallback() { 26 | override fun onCameraAvailable(cameraId: String) { 27 | if (cameraId == targetCameraId) { 28 | unregisterAvailabilityCallback(this) 29 | callback() 30 | } 31 | } 32 | 33 | override fun onCameraUnavailable(cameraId: String) { 34 | if (cameraId == targetCameraId) { 35 | } 36 | } 37 | }, handler) 38 | } 39 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPALTE.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | ## Proposed changes 6 | 7 | Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. If it fixes a bug or resolves a feature request, be sure to link to that issue. 8 | 9 | ## Types of changes 10 | 11 | What types of changes does your code introduce to CameraKit? 12 | _Put an `x` in the boxes that apply_ 13 | 14 | - [ ] Bugfix (non-breaking change which fixes an issue) 15 | - [ ] New feature (non-breaking change which adds functionality) 16 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) 17 | 18 | ## Checklist 19 | 20 | _Put an `x` in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code._ 21 | 22 | - [ ] I have read the [CONTRIBUTING](/CONTRIBUTING.md) doc 23 | - [ ] Lint and unit tests pass locally with my changes 24 | - [ ] I have added tests that prove my fix is effective or that my feature works 25 | - [ ] I have added necessary documentation (if appropriate) 26 | - [ ] Any dependent changes have been merged and published in downstream modules 27 | 28 | ## Further comments 29 | 30 | If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did and what alternatives you considered, etc... 31 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/api/camera1/ext/Parameters.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.api.camera1.ext 2 | 3 | import android.hardware.Camera 4 | import com.camerakit.type.CameraFlash 5 | import com.camerakit.type.CameraSize 6 | 7 | fun Camera.Parameters.getPreviewSizes(): Array { 8 | return supportedPreviewSizes 9 | .map { CameraSize(it.width, it.height) } 10 | .toTypedArray() 11 | } 12 | 13 | fun Camera.Parameters.getPhotoSizes(): Array { 14 | return supportedPictureSizes 15 | .map { CameraSize(it.width, it.height) } 16 | .toTypedArray() 17 | } 18 | 19 | fun Camera.Parameters.getFlashes(): Array { 20 | if (supportedFlashModes == null) { 21 | return emptyArray() 22 | } 23 | 24 | return supportedFlashModes 25 | .filter { 26 | when (it) { 27 | Camera.Parameters.FLASH_MODE_OFF -> true 28 | Camera.Parameters.FLASH_MODE_ON -> true 29 | Camera.Parameters.FLASH_MODE_AUTO -> true 30 | Camera.Parameters.FLASH_MODE_TORCH -> true 31 | else -> false 32 | } 33 | }.map { 34 | when (it) { 35 | Camera.Parameters.FLASH_MODE_OFF -> CameraFlash.OFF 36 | Camera.Parameters.FLASH_MODE_ON -> CameraFlash.ON 37 | Camera.Parameters.FLASH_MODE_AUTO -> CameraFlash.AUTO 38 | Camera.Parameters.FLASH_MODE_TORCH -> CameraFlash.TORCH 39 | else -> CameraFlash.OFF 40 | } 41 | }.toTypedArray() 42 | } 43 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/api/ManagedCameraApi.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.api 2 | 3 | import android.graphics.SurfaceTexture 4 | import com.camerakit.type.CameraFacing 5 | import com.camerakit.type.CameraFlash 6 | import com.camerakit.type.CameraSize 7 | 8 | class ManagedCameraApi(private val delegate: CameraApi) : CameraApi by delegate { 9 | 10 | @Synchronized 11 | override fun open(facing: CameraFacing) { 12 | cameraHandler.run { delegate.open(facing) } 13 | } 14 | 15 | @Synchronized 16 | override fun release() { 17 | cameraHandler.run { delegate.release() } 18 | } 19 | 20 | override fun setPreviewSize(size: CameraSize) { 21 | cameraHandler.run { delegate.setPreviewSize(size) } 22 | } 23 | 24 | @Synchronized 25 | override fun setPreviewOrientation(degrees: Int) { 26 | cameraHandler.run { delegate.setPreviewOrientation(degrees) } 27 | } 28 | 29 | @Synchronized 30 | override fun startPreview(surfaceTexture: SurfaceTexture) { 31 | cameraHandler.run { delegate.startPreview(surfaceTexture) } 32 | } 33 | 34 | @Synchronized 35 | override fun stopPreview() { 36 | cameraHandler.run { delegate.stopPreview() } 37 | } 38 | 39 | @Synchronized 40 | override fun setFlash(flash: CameraFlash) { 41 | cameraHandler.run { delegate.setFlash(flash) } 42 | } 43 | 44 | @Synchronized 45 | override fun setPhotoSize(size: CameraSize) { 46 | cameraHandler.run { delegate.setPhotoSize(size) } 47 | } 48 | 49 | @Synchronized 50 | override fun capturePhoto(callback: (jpeg: ByteArray) -> Unit) { 51 | cameraHandler.run { delegate.capturePhoto(callback) } 52 | } 53 | 54 | } -------------------------------------------------------------------------------- /camerakit/src/main/cpp/libjpeg/include/jchuff.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jchuff.h 3 | * 4 | * Copyright (C) 1991-1997, Thomas G. Lane. 5 | * This file is part of the Independent JPEG Group's software. 6 | * For conditions of distribution and use, see the accompanying README file. 7 | * 8 | * This file contains declarations for Huffman entropy encoding routines 9 | * that are shared between the sequential encoder (jchuff.c) and the 10 | * progressive encoder (jcphuff.c). No other modules need to see these. 11 | */ 12 | 13 | /* The legal range of a DCT coefficient is 14 | * -1024 .. +1023 for 8-bit data; 15 | * -16384 .. +16383 for 12-bit data. 16 | * Hence the magnitude should always fit in 10 or 14 bits respectively. 17 | */ 18 | 19 | #if BITS_IN_JSAMPLE == 8 20 | #define MAX_COEF_BITS 10 21 | #else 22 | #define MAX_COEF_BITS 14 23 | #endif 24 | 25 | /* Derived data constructed for each Huffman table */ 26 | 27 | typedef struct { 28 | unsigned int ehufco[256]; /* code for each symbol */ 29 | char ehufsi[256]; /* length of code for each symbol */ 30 | /* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */ 31 | } c_derived_tbl; 32 | 33 | /* Short forms of external names for systems with brain-damaged linkers. */ 34 | 35 | #ifdef NEED_SHORT_EXTERNAL_NAMES 36 | #define jpeg_make_c_derived_tbl jMkCDerived 37 | #define jpeg_gen_optimal_table jGenOptTbl 38 | #endif /* NEED_SHORT_EXTERNAL_NAMES */ 39 | 40 | /* Expand a Huffman table definition into the derived format */ 41 | EXTERN(void) jpeg_make_c_derived_tbl 42 | JPP((j_compress_ptr cinfo, boolean isDC, int tblno, 43 | c_derived_tbl ** pdtbl)); 44 | 45 | /* Generate an optimal table definition given the specified counts */ 46 | EXTERN(void) jpeg_gen_optimal_table 47 | JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])); 48 | -------------------------------------------------------------------------------- /camerakit/src/main/api16/com/wonderkiln/camerakit/ProcessStillTask.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.graphics.YuvImage; 4 | import android.hardware.Camera; 5 | 6 | class ProcessStillTask implements Runnable { 7 | 8 | private byte[] data; 9 | private Camera camera; 10 | private int rotation; 11 | private OnStillProcessedListener onStillProcessedListener; 12 | 13 | public ProcessStillTask(byte[] data, Camera camera, int rotation, OnStillProcessedListener onStillProcessedListener) { 14 | this.data = data; 15 | this.camera = camera; 16 | this.rotation = rotation; 17 | this.onStillProcessedListener = onStillProcessedListener; 18 | } 19 | 20 | @Override 21 | public void run() { 22 | Camera.Parameters parameters = camera.getParameters(); 23 | int width = parameters.getPreviewSize().width; 24 | int height = parameters.getPreviewSize().height; 25 | byte[] rotatedData = new Rotation(data, width, height, rotation).getYuv(); 26 | 27 | int postWidth; 28 | int postHeight; 29 | 30 | switch (rotation) { 31 | case 90: 32 | case 270: 33 | postWidth = height; 34 | postHeight = width; 35 | break; 36 | 37 | case 0: 38 | case 180: 39 | default: 40 | postWidth = width; 41 | postHeight = height; 42 | break; 43 | } 44 | 45 | YuvImage yuv = new YuvImage(rotatedData, parameters.getPreviewFormat(), postWidth, postHeight, null); 46 | 47 | onStillProcessedListener.onStillProcessed(yuv); 48 | } 49 | 50 | interface OnStillProcessedListener { 51 | void onStillProcessed(YuvImage yuv); 52 | } 53 | 54 | } -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/api/camera2/ext/CameraCharacteristics.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.api.camera2.ext 2 | 3 | import android.graphics.ImageFormat 4 | import android.hardware.camera2.CameraCharacteristics 5 | import androidx.annotation.RequiresApi 6 | import android.view.SurfaceHolder 7 | import com.camerakit.type.CameraFlash 8 | import com.camerakit.type.CameraSize 9 | 10 | @RequiresApi(21) 11 | fun CameraCharacteristics.getSensorOrientation(): Int { 12 | return get(CameraCharacteristics.SENSOR_ORIENTATION) ?: 0 13 | } 14 | 15 | @RequiresApi(21) 16 | fun CameraCharacteristics.getPreviewSizes(): Array { 17 | val streamConfigMap = get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP) 18 | ?: return emptyArray() 19 | 20 | val outputSizes = streamConfigMap.getOutputSizes(SurfaceHolder::class.java) 21 | ?: return emptyArray() 22 | 23 | return outputSizes 24 | .map { CameraSize(it.width, it.height) } 25 | .toTypedArray() 26 | } 27 | 28 | @RequiresApi(21) 29 | fun CameraCharacteristics.getPhotoSizes(): Array { 30 | val streamConfigMap = get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP) 31 | ?: return emptyArray() 32 | 33 | val outputSizes = streamConfigMap.getOutputSizes(ImageFormat.JPEG) 34 | ?: return emptyArray() 35 | 36 | return outputSizes 37 | .map { CameraSize(it.width, it.height) } 38 | .toTypedArray() 39 | } 40 | 41 | @RequiresApi(21) 42 | fun CameraCharacteristics.getFlashes(): Array { 43 | val flashSupported = get(CameraCharacteristics.FLASH_INFO_AVAILABLE) 44 | if (flashSupported) { 45 | return arrayOf(CameraFlash.OFF, CameraFlash.ON, CameraFlash.AUTO, CameraFlash.TORCH) 46 | } else { 47 | return emptyArray() 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /camerakit/src/main/events/com/wonderkiln/camerakit/CameraKitEvent.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.NonNull; 5 | 6 | public class CameraKitEvent { 7 | 8 | public static final String TYPE_ERROR = "CameraKitError"; 9 | 10 | public static final String TYPE_CAMERA_OPEN = "CKCameraOpenedEvent"; 11 | public static final String TYPE_CAMERA_CLOSE = "CKCameraStoppedEvent"; 12 | 13 | public static final String TYPE_FACING_CHANGED = "CKFacingChangedEvent"; 14 | public static final String TYPE_FLASH_CHANGED = "CKFlashChangedEvent"; 15 | 16 | public static final String TYPE_IMAGE_CAPTURED = "CKImageCapturedEvent"; 17 | public static final String TYPE_VIDEO_CAPTURED = "CKVideoCapturedEvent"; 18 | 19 | public static final String TYPE_FOCUS_MOVED = "CKFocusMovedEvent"; 20 | 21 | public static final String TYPE_TEXT_DETECTED = "CKTextDetectedEvent"; 22 | 23 | private String type; 24 | private String message; 25 | 26 | private Bundle data; 27 | 28 | private CameraKitEvent() { 29 | } 30 | 31 | CameraKitEvent(@NonNull String type) { 32 | this.type = type; 33 | data = new Bundle(); 34 | } 35 | 36 | protected void setMessage(String message) { 37 | this.message = message; 38 | } 39 | 40 | @NonNull 41 | public String getType() { 42 | return type; 43 | } 44 | 45 | @NonNull 46 | public String getMessage() { 47 | if (message != null) { 48 | return message; 49 | } 50 | 51 | return ""; 52 | } 53 | 54 | @NonNull 55 | public Bundle getData() { 56 | if (data != null) { 57 | return data; 58 | } 59 | 60 | return new Bundle(); 61 | } 62 | 63 | @Override 64 | public String toString() { 65 | return String.format("%s: %s", getType(), getMessage()); 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /camerakit/src/main/cpp/libjpeg/include/jconfig.h: -------------------------------------------------------------------------------- 1 | /* jconfig.h. Generated from jconfig.h.in by configure. */ 2 | /* Version ID for the JPEG library. 3 | * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". 4 | */ 5 | #define JPEG_LIB_VERSION 62 6 | 7 | /* Support arithmetic encoding */ 8 | #define C_ARITH_CODING_SUPPORTED 1 9 | 10 | /* Support arithmetic decoding */ 11 | #define D_ARITH_CODING_SUPPORTED 1 12 | 13 | /* Define if your compiler supports prototypes */ 14 | #define HAVE_PROTOTYPES 1 15 | 16 | /* Define to 1 if you have the header file. */ 17 | #define HAVE_STDDEF_H 1 18 | 19 | /* Define to 1 if you have the header file. */ 20 | #define HAVE_STDLIB_H 1 21 | 22 | /* Define to 1 if the system has the type `unsigned char'. */ 23 | #define HAVE_UNSIGNED_CHAR 1 24 | 25 | /* Define to 1 if the system has the type `unsigned short'. */ 26 | #define HAVE_UNSIGNED_SHORT 1 27 | 28 | /* Define if you want use complete types */ 29 | /* #undef INCOMPLETE_TYPES_BROKEN */ 30 | 31 | /* Define if you have BSD-like bzero and bcopy */ 32 | /* #undef NEED_BSD_STRINGS */ 33 | 34 | /* Define if you need short function names */ 35 | /* #undef NEED_SHORT_EXTERNAL_NAMES */ 36 | 37 | /* Define if you have sys/types.h */ 38 | #define NEED_SYS_TYPES_H 1 39 | 40 | /* Define if shift is unsigned */ 41 | /* #undef RIGHT_SHIFT_IS_UNSIGNED */ 42 | 43 | /* Use accelerated SIMD routines. */ 44 | #define WITH_SIMD 1 45 | 46 | /* Define to 1 if type `char' is unsigned and you are not using gcc. */ 47 | #ifndef __CHAR_UNSIGNED__ 48 | /* # undef __CHAR_UNSIGNED__ */ 49 | #endif 50 | 51 | /* Define to empty if `const' does not conform to ANSI C. */ 52 | /* #undef const */ 53 | 54 | /* Define to `__inline__' or `__inline' if that's what the C compiler 55 | calls it, or to nothing if 'inline' is not supported under any name. */ 56 | #ifndef __cplusplus 57 | /* #undef inline */ 58 | #endif 59 | 60 | /* Define to `unsigned int' if does not define. */ 61 | /* #undef size_t */ 62 | 63 | -------------------------------------------------------------------------------- /camerakit/src/main/utils/com/wonderkiln/camerakit/Rotation.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | public class Rotation { 4 | 5 | private byte[] rotatedYuv; 6 | 7 | public Rotation(final byte[] yuv, final int width, final int height, final int rotation) { 8 | if (rotation == 0) this.rotatedYuv = yuv; 9 | if (rotation % 90 != 0 || rotation < 0 || rotation > 270) { 10 | throw new IllegalArgumentException("0 <= rotation < 360, rotation % 90 == 0"); 11 | } 12 | 13 | final byte[] output = new byte[yuv.length]; 14 | final int frameSize = width * height; 15 | final boolean swap = rotation % 180 != 0; 16 | final boolean xflip = rotation % 270 != 0; 17 | final boolean yflip = rotation >= 180; 18 | 19 | for (int j = 0; j < height; j++) { 20 | for (int i = 0; i < width; i++) { 21 | final int yIn = j * width + i; 22 | final int uIn = frameSize + (j >> 1) * width + (i & ~1); 23 | final int vIn = uIn + 1; 24 | 25 | final int wOut = swap ? height : width; 26 | final int hOut = swap ? width : height; 27 | final int iSwapped = swap ? j : i; 28 | final int jSwapped = swap ? i : j; 29 | final int iOut = xflip ? wOut - iSwapped - 1 : iSwapped; 30 | final int jOut = yflip ? hOut - jSwapped - 1 : jSwapped; 31 | 32 | final int yOut = jOut * wOut + iOut; 33 | final int uOut = frameSize + (jOut >> 1) * wOut + (iOut & ~1); 34 | final int vOut = uOut + 1; 35 | 36 | output[yOut] = (byte) (0xff & yuv[yIn]); 37 | output[uOut] = (byte) (0xff & yuv[uIn]); 38 | output[vOut] = (byte) (0xff & yuv[vIn]); 39 | } 40 | } 41 | 42 | this.rotatedYuv = output; 43 | } 44 | 45 | public byte[] getYuv() { 46 | return this.rotatedYuv; 47 | } 48 | 49 | } 50 | 51 | -------------------------------------------------------------------------------- /camerakit/src/main/base/com/wonderkiln/camerakit/PreviewImpl.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.graphics.SurfaceTexture; 4 | import android.view.Surface; 5 | import android.view.SurfaceHolder; 6 | import android.view.View; 7 | 8 | abstract class PreviewImpl { 9 | 10 | interface Callback { 11 | void onSurfaceChanged(); 12 | } 13 | 14 | private Callback mCallback; 15 | 16 | private int mWidth; 17 | private int mHeight; 18 | 19 | protected int mPreviewWidth; 20 | protected int mPreviewHeight; 21 | protected int mPreviewFormat; 22 | 23 | void setCallback(Callback callback) { 24 | mCallback = callback; 25 | } 26 | 27 | abstract Surface getSurface(); 28 | 29 | abstract View getView(); 30 | 31 | abstract Class getOutputClass(); 32 | 33 | abstract void setDisplayOrientation(int displayOrientation); 34 | 35 | abstract boolean isReady(); 36 | 37 | protected void dispatchSurfaceChanged() { 38 | mCallback.onSurfaceChanged(); 39 | } 40 | 41 | SurfaceHolder getSurfaceHolder() { 42 | return null; 43 | } 44 | 45 | SurfaceTexture getSurfaceTexture() { 46 | return null; 47 | } 48 | 49 | void setSize(int width, int height) { 50 | mWidth = width; 51 | mHeight = height; 52 | } 53 | 54 | int getWidth() { 55 | return mWidth; 56 | } 57 | 58 | int getHeight() { 59 | return mHeight; 60 | } 61 | 62 | abstract float getX(); 63 | abstract float getY(); 64 | 65 | void setPreviewParameters(final int width, final int height, final int format) { 66 | this.mPreviewWidth = width; 67 | this.mPreviewHeight = height; 68 | this.mPreviewFormat = format; 69 | } 70 | 71 | int getPreviewWidth() { 72 | return mPreviewWidth; 73 | } 74 | 75 | int getPreviewHeight() { 76 | return mPreviewHeight; 77 | } 78 | 79 | int getPreviewFormat() { 80 | return mPreviewFormat; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /camerakit/src/main/cpp/libjpeg/include/bmp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C)2011 D. R. Commander. All Rights Reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright notice, 10 | * this list of conditions and the following disclaimer in the documentation 11 | * and/or other materials provided with the distribution. 12 | * - Neither the name of the libjpeg-turbo Project nor the names of its 13 | * contributors may be used to endorse or promote products derived from this 14 | * software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef __BMP_H__ 30 | #define __BMP_H__ 31 | 32 | #include "./turbojpeg.h" 33 | 34 | int loadbmp(char *filename, unsigned char **buf, int *w, int *h, int pf, 35 | int bottomup); 36 | 37 | int savebmp(char *filename, unsigned char *buf, int w, int h, int pf, 38 | int bottomup); 39 | 40 | const char *bmpgeterr(void); 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /.github/TESTING_PROCEDURES.md: -------------------------------------------------------------------------------- 1 | # CameraKit Testing Procedures 2 | 3 | For each release we plan to run all code changes through a specific flow and test regiment, on varying devicews. THe report of these tests will be reported via a comment or in the PR Header ahead of any and all merges. 4 | 5 | ## Tests 6 | ### Test Photo Capture (Portrait) 7 | 8 | - Open CameraKit 9 | - Take single photo 10 | - Verify photo is created and saved as Portrait Photo 11 | - Verify photo is in-focus, and error free 12 | 13 | ### Test Photo Capture (Landscape) 14 | 15 | - Open CameraKit 16 | - Take single photo 17 | - Verify photo is created and saved as Landscape Photo 18 | - Verify photo is in-focus, and error free 19 | 20 | ### Test Orientation Capture 21 | 22 | - Change Orientation to 90, 180, 270, 0 (with orientation lock OFF) 23 | - Confirm Preview Updates properly for each orietantation 24 | - Capture Photo for each orientation, confirm result matches preview 25 | 26 | ### Test Orientation Capture w/ Orientation Lock ON 27 | 28 | - Change Orientation to 90, 180, 270, 0 (with orientation lock ON) 29 | - Confirm Preview Updates properly for each orietantation 30 | - Capture Photo for each orientation, confirm result matches preview 31 | 32 | ### Engage Camera Controls and Take Photo (Portrait) 33 | 34 | - Open CameraKit 35 | - Tap to Focus and Take Photo 36 | - Confirm preview focuses correctly 37 | - COnfirm saved photo matches preview 38 | - Pinch to Zoom (In + Out) and Take Photo 39 | - Confirm preview zooms correctly 40 | - COnfirm saved photo matches preview 41 | - Take single photo 42 | - Verify photo is created and saved as Landscape Photo 43 | - Verify photo is in-focus, and error free 44 | 45 | ### Test Camera under Rapid Fire 46 | 47 | - Open CameraKit 48 | - Take succesive photos (30 within 30s) 49 | - Verify all 30 photos are created and saved 50 | - Verify each photo appears without error 51 | 52 | 53 | ## Devices being tested on 54 | - Essential Phone 55 | - Google Pixel 56 | - Samsung Galaxy S8 57 | 58 | Want to request a device? Make a issue in Github! =) 59 | -------------------------------------------------------------------------------- /camerakit/src/main/utils/com/wonderkiln/camerakit/YuvOperator.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | public class YuvOperator { 6 | 7 | private ByteBuffer handler; 8 | 9 | private int width; 10 | private int height; 11 | 12 | private YuvOperator() { 13 | } 14 | 15 | public YuvOperator(byte[] yuv, int width, int height) { 16 | if (width*height != yuv.length) return; 17 | storeYuvData(yuv, width, height); 18 | this.width = width; 19 | this.height = height; 20 | } 21 | 22 | private void storeYuvData(byte[] yuv, int width, int height) { 23 | if (handler != null) freeYuvData(); 24 | handler = jniStoreYuvData(yuv, width, height); 25 | } 26 | 27 | public void rotate(int rotation) { 28 | if (handler == null) return; 29 | if (rotation == 90) jniRotateYuvCw90(handler); 30 | else if (rotation == 180) jniRotateYuv180(handler); 31 | else if (rotation == 270) jniRotateYuvCcw90(handler); 32 | } 33 | 34 | public byte[] getYuvData() { 35 | if (handler == null) return null; 36 | byte[] yuv = jniGetYuvData(handler); 37 | freeYuvData(); 38 | return yuv; 39 | } 40 | 41 | private void freeYuvData() { 42 | if (handler == null) return; 43 | jniFreeYuvData(handler); 44 | handler = null; 45 | } 46 | 47 | @Override 48 | protected void finalize() throws Throwable { 49 | super.finalize(); 50 | if (handler == null) return; 51 | freeYuvData(); 52 | } 53 | 54 | static { 55 | System.loadLibrary("yuvOperator"); 56 | } 57 | 58 | private native ByteBuffer jniStoreYuvData(byte[] data, int width, int height); 59 | 60 | private native void jniRotateYuvCcw90(ByteBuffer handler); 61 | 62 | private native void jniRotateYuvCw90(ByteBuffer handler); 63 | 64 | private native void jniRotateYuv180(ByteBuffer handler); 65 | 66 | private native byte[] jniGetYuvData(ByteBuffer handler); 67 | 68 | private native void jniFreeYuvData(ByteBuffer handler); 69 | 70 | } 71 | -------------------------------------------------------------------------------- /camerakit/src/main/cpp/libjpeg/include/tjutil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C)2011 D. R. Commander. All Rights Reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright notice, 10 | * this list of conditions and the following disclaimer in the documentation 11 | * and/or other materials provided with the distribution. 12 | * - Neither the name of the libjpeg-turbo Project nor the names of its 13 | * contributors may be used to endorse or promote products derived from this 14 | * software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifdef _WIN32 30 | #ifndef __MINGW32__ 31 | #include 32 | #define snprintf(str, n, format, ...) \ 33 | _snprintf_s(str, n, _TRUNCATE, format, __VA_ARGS__) 34 | #endif 35 | #define strcasecmp stricmp 36 | #define strncasecmp strnicmp 37 | #endif 38 | 39 | #ifndef min 40 | #define min(a,b) ((a)<(b)?(a):(b)) 41 | #endif 42 | 43 | #ifndef max 44 | #define max(a,b) ((a)>(b)?(a):(b)) 45 | #endif 46 | 47 | extern double gettime(void); 48 | -------------------------------------------------------------------------------- /camerakit/src/main/utils/com/wonderkiln/camerakit/JpegTransformer.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.graphics.Rect; 4 | 5 | import java.nio.ByteBuffer; 6 | 7 | public class JpegTransformer { 8 | 9 | private ByteBuffer mHandler; 10 | 11 | public JpegTransformer(byte[] jpeg) { 12 | mHandler = jniStoreJpeg(jpeg, jpeg.length); 13 | } 14 | 15 | public byte[] getJpeg() { 16 | if (mHandler == null) return null; 17 | return jniCommit(mHandler); 18 | } 19 | 20 | public int getWidth() { 21 | if (mHandler == null) return 0; 22 | return jniGetWidth(mHandler); 23 | } 24 | 25 | public int getHeight() { 26 | if (mHandler == null) return 0; 27 | return jniGetHeight(mHandler); 28 | } 29 | 30 | public void rotate(int degrees) { 31 | if (mHandler != null) { 32 | jniRotate(mHandler, degrees); 33 | } 34 | } 35 | 36 | public void flipHorizontal() { 37 | if (mHandler != null) { 38 | jniFlipHorizontal(mHandler); 39 | } 40 | } 41 | 42 | public void flipVertical() { 43 | if (mHandler != null) { 44 | jniFlipVertical(mHandler); 45 | } 46 | } 47 | 48 | public void crop(Rect crop) { 49 | if (mHandler != null) { 50 | jniCrop(mHandler, crop.left, crop.top, crop.width(), crop.height()); 51 | } 52 | } 53 | 54 | static { 55 | System.loadLibrary("yuvOperator"); 56 | System.loadLibrary("jpegTransformer"); 57 | } 58 | 59 | private native ByteBuffer jniStoreJpeg(byte[] jpeg, int size); 60 | 61 | private native byte[] jniCommit(ByteBuffer handler); 62 | 63 | private native int jniGetWidth(ByteBuffer handler); 64 | 65 | private native int jniGetHeight(ByteBuffer handler); 66 | 67 | private native void jniRotate(ByteBuffer handler, int degrees); 68 | 69 | private native void jniFlipHorizontal(ByteBuffer handler); 70 | 71 | private native void jniFlipVertical(ByteBuffer handler); 72 | 73 | private native void jniCrop(ByteBuffer handler, int left, int top, int width, int height); 74 | 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/logomark_light.xml: -------------------------------------------------------------------------------- 1 | 6 | 12 | 18 | 24 | 25 | -------------------------------------------------------------------------------- /camerakit/src/main/base/com/wonderkiln/camerakit/CameraImpl.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.support.annotation.Nullable; 4 | 5 | import com.google.android.gms.vision.Detector; 6 | import com.google.android.gms.vision.text.TextBlock; 7 | 8 | import java.io.File; 9 | 10 | abstract class CameraImpl { 11 | 12 | protected final EventDispatcher mEventDispatcher; 13 | protected final PreviewImpl mPreview; 14 | 15 | CameraImpl(EventDispatcher eventDispatcher, PreviewImpl preview) { 16 | mEventDispatcher = eventDispatcher; 17 | mPreview = preview; 18 | } 19 | 20 | abstract void start(); 21 | abstract void stop(); 22 | 23 | abstract void setDisplayAndDeviceOrientation(int displayOrientation, int deviceOrientation); 24 | 25 | abstract void setFacing(@Facing int facing); 26 | abstract void setFlash(@Flash int flash); 27 | abstract void setFocus(@Focus int focus); 28 | abstract void setMethod(@CaptureMethod int method); 29 | abstract void setTextDetector(Detector detector); 30 | 31 | abstract void setVideoQuality(@VideoQuality int videoQuality); 32 | abstract void setVideoBitRate(int videoBitRate); 33 | abstract void setLockVideoAspectRatio(boolean lockVideoAspectRatio); 34 | 35 | abstract void setZoom(float zoomFactor); 36 | abstract void modifyZoom(float modifier); 37 | abstract void setFocusArea(float x, float y); 38 | 39 | abstract void captureImage(ImageCapturedCallback callback); 40 | interface ImageCapturedCallback { 41 | void imageCaptured(byte[] jpeg); 42 | } 43 | 44 | void captureVideo(File videoFile, VideoCapturedCallback callback) { 45 | captureVideo(videoFile, 0, callback); 46 | } 47 | 48 | abstract void captureVideo(File videoFile, int maxDuration, VideoCapturedCallback callback); 49 | interface VideoCapturedCallback { 50 | void videoCaptured(File file); 51 | } 52 | 53 | abstract void stopVideo(); 54 | 55 | abstract Size getCaptureResolution(); 56 | abstract Size getVideoResolution(); 57 | abstract Size getPreviewResolution(); 58 | abstract boolean isCameraOpened(); 59 | abstract boolean frontCameraOnly(); 60 | 61 | @Nullable 62 | abstract CameraProperties getCameraProperties(); 63 | 64 | } 65 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/preview/CameraSurfaceTexture.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.preview 2 | 3 | import android.graphics.SurfaceTexture 4 | import android.opengl.Matrix 5 | import androidx.annotation.Keep 6 | import com.camerakit.type.CameraSize 7 | 8 | class CameraSurfaceTexture(inputTexture: Int, val outputTexture: Int) : SurfaceTexture(inputTexture) { 9 | 10 | var size: CameraSize = CameraSize(0, 0) 11 | set(size) { 12 | field = size 13 | previewInvalidated = true 14 | } 15 | 16 | private var previewInvalidated = false 17 | private val transformMatrix: FloatArray = FloatArray(16) 18 | private val extraTransformMatrix: FloatArray = FloatArray(16) 19 | 20 | init { 21 | nativeInit(inputTexture, outputTexture) 22 | Matrix.setIdentityM(extraTransformMatrix, 0) 23 | } 24 | 25 | override fun updateTexImage() { 26 | if (previewInvalidated) { 27 | nativeSetSize(size.width, size.height) 28 | previewInvalidated = false 29 | } 30 | 31 | super.updateTexImage() 32 | getTransformMatrix(transformMatrix) 33 | nativeUpdateTexImage(transformMatrix, extraTransformMatrix) 34 | } 35 | 36 | override fun release() { 37 | nativeRelease() 38 | } 39 | 40 | fun setRotation(degrees: Int) { 41 | Matrix.setIdentityM(extraTransformMatrix, 0) 42 | Matrix.rotateM(extraTransformMatrix, 0, degrees.toFloat(), 0f, 0f, 1f) 43 | } 44 | 45 | // --- 46 | 47 | override fun finalize() { 48 | super.finalize() 49 | try { 50 | nativeFinalize() 51 | } catch (e: Exception) { 52 | // ignore 53 | } 54 | } 55 | 56 | // --- 57 | 58 | @Keep 59 | private var nativeHandle: Long = 0L 60 | 61 | private external fun nativeInit(inputTexture: Int, outputTexture: Int) 62 | 63 | private external fun nativeSetSize(width: Int, height: Int) 64 | 65 | private external fun nativeUpdateTexImage(transformMatrix: FloatArray, extraTransformMatrix: FloatArray) 66 | 67 | private external fun nativeFinalize() 68 | 69 | private external fun nativeRelease() 70 | 71 | companion object { 72 | 73 | init { 74 | System.loadLibrary("camerakit") 75 | } 76 | 77 | } 78 | 79 | } 80 | 81 | -------------------------------------------------------------------------------- /camerakit/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/launch_bg.xml: -------------------------------------------------------------------------------- 1 | 6 | 11 | 17 | 23 | 29 | 30 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto operate 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto operate 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :operate 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/wonderkiln/camerakit/CameraKit.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.content.res.Resources; 4 | 5 | public class CameraKit { 6 | 7 | static class Internal { 8 | 9 | static final int screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels; 10 | static final int screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels; 11 | 12 | } 13 | 14 | public static class Constants { 15 | 16 | public static final int PERMISSION_REQUEST_CAMERA = 16; 17 | 18 | public static final int FACING_BACK = 0; 19 | public static final int FACING_FRONT = 1; 20 | 21 | public static final int FLASH_OFF = 0; 22 | public static final int FLASH_ON = 1; 23 | public static final int FLASH_AUTO = 2; 24 | public static final int FLASH_TORCH = 3; 25 | 26 | public static final int FOCUS_OFF = 0; 27 | public static final int FOCUS_CONTINUOUS = 1; 28 | public static final int FOCUS_TAP = 2; 29 | public static final int FOCUS_TAP_WITH_MARKER = 3; 30 | 31 | public static final int METHOD_STANDARD = 0; 32 | public static final int METHOD_STILL = 1; 33 | 34 | public static final int PERMISSIONS_STRICT = 0; 35 | public static final int PERMISSIONS_LAZY = 1; 36 | public static final int PERMISSIONS_PICTURE = 2; 37 | 38 | public static final int VIDEO_QUALITY_480P = 0; 39 | public static final int VIDEO_QUALITY_720P = 1; 40 | public static final int VIDEO_QUALITY_1080P = 2; 41 | public static final int VIDEO_QUALITY_2160P = 3; 42 | public static final int VIDEO_QUALITY_HIGHEST = 4; 43 | public static final int VIDEO_QUALITY_LOWEST = 5; 44 | public static final int VIDEO_QUALITY_QVGA = 6; 45 | 46 | } 47 | 48 | static class Defaults { 49 | 50 | static final int DEFAULT_FACING = Constants.FACING_BACK; 51 | static final int DEFAULT_FLASH = Constants.FLASH_OFF; 52 | static final int DEFAULT_FOCUS = Constants.FOCUS_CONTINUOUS; 53 | static final boolean DEFAULT_PINCH_TO_ZOOM = true; 54 | static final float DEFAULT_ZOOM = 1.f; 55 | static final int DEFAULT_METHOD = Constants.METHOD_STANDARD; 56 | static final int DEFAULT_PERMISSIONS = Constants.PERMISSIONS_STRICT; 57 | static final int DEFAULT_VIDEO_QUALITY = Constants.VIDEO_QUALITY_480P; 58 | 59 | static final int DEFAULT_JPEG_QUALITY = 100; 60 | static final int DEFAULT_VIDEO_BIT_RATE = 0; 61 | static final boolean DEFAULT_CROP_OUTPUT = false; 62 | static final boolean DEFAULT_DOUBLE_TAP_TO_TOGGLE_FACING = false; 63 | static final boolean DEFAULT_ADJUST_VIEW_BOUNDS = false; 64 | 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/wonderkiln/camerakit/FocusMarkerLayout.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.animation.Animator; 4 | import android.animation.AnimatorListenerAdapter; 5 | import android.content.Context; 6 | import android.support.annotation.NonNull; 7 | import android.support.annotation.Nullable; 8 | import android.util.AttributeSet; 9 | import android.view.LayoutInflater; 10 | import android.widget.FrameLayout; 11 | import android.widget.ImageView; 12 | 13 | import com.wonderkiln.camerakit.core.R; 14 | 15 | public class FocusMarkerLayout extends FrameLayout { 16 | 17 | private FrameLayout mFocusMarkerContainer; 18 | private ImageView mFill; 19 | 20 | public FocusMarkerLayout(@NonNull Context context) { 21 | this(context, null); 22 | } 23 | 24 | public FocusMarkerLayout(@NonNull Context context, @Nullable AttributeSet attrs) { 25 | super(context, attrs); 26 | LayoutInflater.from(getContext()).inflate(R.layout.layout_focus_marker, this); 27 | 28 | mFocusMarkerContainer = findViewById(R.id.focusMarkerContainer); 29 | mFill = findViewById(R.id.fill); 30 | 31 | mFocusMarkerContainer.setAlpha(0); 32 | } 33 | 34 | public void focus(float mx, float my) { 35 | mx *= getWidth(); 36 | my *= getHeight(); 37 | int x = (int) (mx - mFocusMarkerContainer.getWidth() / 2); 38 | int y = (int) (my - mFocusMarkerContainer.getWidth() / 2); 39 | 40 | mFocusMarkerContainer.setTranslationX(x); 41 | mFocusMarkerContainer.setTranslationY(y); 42 | 43 | mFocusMarkerContainer.animate().setListener(null).cancel(); 44 | mFill.animate().setListener(null).cancel(); 45 | 46 | mFill.setScaleX(0); 47 | mFill.setScaleY(0); 48 | mFill.setAlpha(1f); 49 | 50 | mFocusMarkerContainer.setScaleX(1.36f); 51 | mFocusMarkerContainer.setScaleY(1.36f); 52 | mFocusMarkerContainer.setAlpha(1f); 53 | 54 | mFocusMarkerContainer.animate().scaleX(1).scaleY(1).setStartDelay(0).setDuration(330) 55 | .setListener(new AnimatorListenerAdapter() { 56 | @Override 57 | public void onAnimationEnd(Animator animation) { 58 | super.onAnimationEnd(animation); 59 | mFocusMarkerContainer.animate().alpha(0).setStartDelay(750).setDuration(800).setListener(null).start(); 60 | } 61 | }).start(); 62 | 63 | mFill.animate().scaleX(1).scaleY(1).setDuration(330) 64 | .setListener(new AnimatorListenerAdapter() { 65 | @Override 66 | public void onAnimationEnd(Animator animation) { 67 | super.onAnimationEnd(animation); 68 | mFill.animate().alpha(0).setDuration(800).setListener(null).start(); 69 | } 70 | }).start(); 71 | 72 | } 73 | 74 | 75 | } 76 | -------------------------------------------------------------------------------- /camerakit/deploy.gradle: -------------------------------------------------------------------------------- 1 | def getBintrayUser() { 2 | if (System.getenv('BINTRAY_USER')) { 3 | return System.getenv('BINTRAY_USER') 4 | } 5 | 6 | if (rootProject.file('local.properties').exists()) { 7 | Properties properties = new Properties() 8 | properties.load(rootProject.file('local.properties').newDataInputStream()) 9 | return properties.getProperty('bintray.user') 10 | } 11 | } 12 | 13 | def getBintrayKey() { 14 | if (System.getenv('BINTRAY_KEY')) { 15 | return System.getenv('BINTRAY_KEY') 16 | } 17 | 18 | if (rootProject.file('local.properties').exists()) { 19 | Properties properties = new Properties() 20 | properties.load(rootProject.file('local.properties').newDataInputStream()) 21 | return properties.getProperty('bintray.key') 22 | } 23 | } 24 | 25 | apply plugin: 'com.jfrog.bintray' 26 | 27 | bintray { 28 | user = getBintrayUser() 29 | key = getBintrayKey() 30 | configurations = ['archives'] 31 | pkg { 32 | repo = 'camerakit-v1-prereleases' 33 | name = 'camerakit-android' 34 | userOrg = 'camerakit' 35 | vcsUrl = 'https://github.com/CameraKit/camerakit-android.git' 36 | licenses = ['MIT'] 37 | 38 | version { 39 | name = project.version 40 | released = new Date() 41 | } 42 | } 43 | } 44 | 45 | task cleanForDeployment { 46 | doLast { 47 | logger.lifecycle('Deployment: Cleaning...') 48 | logger.lifecycle('Deleting: ' + project.buildDir) 49 | delete project.buildDir 50 | } 51 | } 52 | 53 | task buildForDeployment { 54 | shouldRunAfter(cleanForDeployment) 55 | finalizedBy assemble 56 | 57 | doFirst { 58 | android.variantFilter { variant -> 59 | if (variant.buildType.name == 'debug') { 60 | variant.setIgnore(true) 61 | } 62 | } 63 | } 64 | } 65 | 66 | task deploySnapshot { 67 | shouldRunAfter(buildForDeployment) 68 | 69 | dependsOn cleanForDeployment 70 | dependsOn buildForDeployment 71 | finalizedBy bintrayUpload 72 | 73 | doLast { 74 | version = version + '-Snapshot' 75 | bintrayUpload.setVersionName(bintrayUpload.getVersionName() + '-Snapshot') 76 | bintrayUpload.setUserOrg('camerakit') 77 | bintrayUpload.setRepoName('camerakit-android-snapshots') 78 | bintrayUpload.setOverride(true) 79 | bintrayUpload.setPublish(true) 80 | 81 | logger.lifecycle('Deploying version ' + bintrayUpload.getVersionName() + ' in ' + bintrayUpload.getRepoName()) 82 | } 83 | } 84 | 85 | task deployRelease { 86 | shouldRunAfter(buildForDeployment) 87 | 88 | dependsOn cleanForDeployment 89 | dependsOn buildForDeployment 90 | finalizedBy bintrayUpload 91 | 92 | doLast { 93 | bintrayUpload.setUserOrg('camerakit') 94 | bintrayUpload.setRepoName('camerakit-v1-prereleases') 95 | 96 | logger.lifecycle('Deploying version ' + bintrayUpload.getVersionName() + ' in ' + bintrayUpload.getRepoName()) 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /camerakit/src/main/base/com/wonderkiln/camerakit/CameraViewLayout.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import android.util.AttributeSet; 7 | import android.view.GestureDetector; 8 | import android.view.MotionEvent; 9 | import android.view.ScaleGestureDetector; 10 | import android.widget.FrameLayout; 11 | 12 | public abstract class CameraViewLayout extends FrameLayout { 13 | 14 | private ScaleGestureDetector scaleGestureDetector; 15 | private GestureDetector gestureDetector; 16 | 17 | public CameraViewLayout(@NonNull Context context) { 18 | this(context, null); 19 | } 20 | 21 | public CameraViewLayout(@NonNull Context context, @Nullable AttributeSet attrs) { 22 | this(context, attrs, 0); 23 | } 24 | 25 | public CameraViewLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 26 | super(context, attrs, defStyleAttr); 27 | gestureDetector = new GestureDetector(context, onGestureListener); 28 | scaleGestureDetector = new ScaleGestureDetector(context, onScaleGestureListener); 29 | } 30 | 31 | @Override 32 | public boolean onTouchEvent(MotionEvent event) { 33 | gestureDetector.onTouchEvent(event); 34 | scaleGestureDetector.onTouchEvent(event); 35 | return true; 36 | } 37 | 38 | @Override 39 | public boolean onInterceptTouchEvent(MotionEvent ev) { 40 | return true; 41 | } 42 | 43 | protected abstract CameraImpl getCameraImpl(); 44 | 45 | protected abstract PreviewImpl getPreviewImpl(); 46 | 47 | protected abstract void onZoom(float zoom, boolean start); 48 | 49 | protected abstract void onTapToFocus(float x, float y); 50 | 51 | protected abstract void onToggleFacing(); 52 | 53 | private GestureDetector.SimpleOnGestureListener onGestureListener = new GestureDetector.SimpleOnGestureListener() { 54 | 55 | @Override 56 | public boolean onDoubleTap(MotionEvent e) { 57 | onToggleFacing(); 58 | return super.onDoubleTap(e); 59 | } 60 | 61 | @Override 62 | public boolean onSingleTapConfirmed(MotionEvent e) { 63 | onTapToFocus(e.getX() / (float) getWidth(), e.getY() / (float) getHeight()); 64 | return super.onSingleTapConfirmed(e); 65 | } 66 | }; 67 | 68 | private ScaleGestureDetector.OnScaleGestureListener onScaleGestureListener = new ScaleGestureDetector.OnScaleGestureListener() { 69 | 70 | @Override 71 | public boolean onScale(ScaleGestureDetector scaleGestureDetector) { 72 | onZoom(scaleGestureDetector.getScaleFactor(), false); 73 | return true; 74 | } 75 | 76 | @Override 77 | public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector) { 78 | onZoom(scaleGestureDetector.getScaleFactor(), true); 79 | return true; 80 | } 81 | 82 | @Override 83 | public void onScaleEnd(ScaleGestureDetector scaleGestureDetector) { 84 | } 85 | 86 | }; 87 | 88 | } 89 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | ### Is this a bug report? 6 | 7 | (write your answer here) 8 | 9 | 24 | 25 | ### Have you read the [Contributing Guidelines](CONTRIBUTING.md)? 26 | 27 | (Write your answer here.) 28 | 29 | ### Environment 30 | 31 | (Please include the following information along with any other relevant environment details.) 32 | 33 | CameraKit Version: 34 | 35 | Android Device: 36 | 37 | Android Version: 38 | 39 | ### Steps to Reproduce 40 | 41 | 46 | 47 | (Write your steps here:) 48 | 49 | 1. 50 | 2. 51 | 3. 52 | 53 | ### Expected Behavior 54 | 55 | 60 | 61 | (Write what you thought would happen.) 62 | 63 | ### Actual Behavior 64 | 65 | 71 | 72 | (Write what happened. Add screenshots!) 73 | 74 | ### Reproducible Demo 75 | 76 | 79 | 80 | (Paste the link to an example project and exact instructions to reproduce the issue.) 81 | 82 | (Include your CameraKit setup and usage.) 83 | 98 | 99 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@camerakit.io. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /.repo/gh-join-spectrum.svg: -------------------------------------------------------------------------------- 1 | Join Spectrum -------------------------------------------------------------------------------- /camerakit/src/main/api16/com/wonderkiln/camerakit/ConstantMapper.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.annotation.TargetApi; 4 | import android.hardware.Camera; 5 | import android.hardware.camera2.CameraCharacteristics; 6 | import android.support.v4.util.SparseArrayCompat; 7 | import android.util.SparseIntArray; 8 | 9 | public class ConstantMapper { 10 | 11 | private abstract static class BaseMapper { 12 | 13 | protected int mCameraKitConstant; 14 | 15 | protected BaseMapper(int cameraKitConstant) { 16 | this.mCameraKitConstant = cameraKitConstant; 17 | } 18 | 19 | abstract T map(); 20 | 21 | } 22 | 23 | static class Flash extends BaseMapper { 24 | 25 | private static final SparseArrayCompat FLASH_MODES = new SparseArrayCompat<>(); 26 | 27 | static { 28 | FLASH_MODES.put(CameraKit.Constants.FLASH_OFF, Camera.Parameters.FLASH_MODE_OFF); 29 | FLASH_MODES.put(CameraKit.Constants.FLASH_ON, Camera.Parameters.FLASH_MODE_ON); 30 | FLASH_MODES.put(CameraKit.Constants.FLASH_AUTO, Camera.Parameters.FLASH_MODE_AUTO); 31 | FLASH_MODES.put(CameraKit.Constants.FLASH_TORCH, Camera.Parameters.FLASH_MODE_TORCH); 32 | } 33 | 34 | protected Flash(int cameraKitConstant) { 35 | super(cameraKitConstant); 36 | } 37 | 38 | @Override 39 | String map() { 40 | return FLASH_MODES.get(mCameraKitConstant, FLASH_MODES.get(CameraKit.Constants.FLASH_OFF)); 41 | } 42 | 43 | } 44 | 45 | @TargetApi(21) 46 | static class Flash2 extends BaseMapper { 47 | 48 | protected Flash2(int cameraKitConstant) { 49 | super(cameraKitConstant); 50 | } 51 | 52 | @Override 53 | String map() { 54 | return null; 55 | } 56 | 57 | } 58 | 59 | static class Facing extends BaseMapper { 60 | 61 | private static final SparseArrayCompat FACING_MODES = new SparseArrayCompat<>(); 62 | 63 | static { 64 | FACING_MODES.put(CameraKit.Constants.FACING_BACK, Camera.CameraInfo.CAMERA_FACING_BACK); 65 | FACING_MODES.put(CameraKit.Constants.FACING_FRONT, Camera.CameraInfo.CAMERA_FACING_FRONT); 66 | } 67 | 68 | protected Facing(int cameraKitConstant) { 69 | super(cameraKitConstant); 70 | } 71 | 72 | @Override 73 | Integer map() { 74 | return FACING_MODES.get(mCameraKitConstant, FACING_MODES.get(CameraKit.Constants.FACING_BACK)); 75 | } 76 | 77 | } 78 | 79 | @TargetApi(21) 80 | static class Facing2 extends BaseMapper { 81 | 82 | private static final SparseIntArray FACING_MODES = new SparseIntArray(); 83 | 84 | static { 85 | FACING_MODES.put(CameraKit.Constants.FACING_BACK, CameraCharacteristics.LENS_FACING_BACK); 86 | FACING_MODES.put(CameraKit.Constants.FACING_FRONT, CameraCharacteristics.LENS_FACING_FRONT); 87 | } 88 | 89 | protected Facing2(int cameraKitConstant) { 90 | super(cameraKitConstant); 91 | } 92 | 93 | @Override 94 | Integer map() { 95 | return FACING_MODES.get(mCameraKitConstant, FACING_MODES.get(CameraKit.Constants.FACING_BACK)); 96 | } 97 | 98 | } 99 | 100 | 101 | } 102 | -------------------------------------------------------------------------------- /camerakit/src/main/base/com/wonderkiln/camerakit/SurfaceViewContainer.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import android.util.AttributeSet; 7 | import android.view.View; 8 | import android.widget.FrameLayout; 9 | 10 | public class SurfaceViewContainer extends FrameLayout { 11 | 12 | private Size mPreviewSize; 13 | private int mDisplayOrientation; 14 | 15 | public SurfaceViewContainer(@NonNull Context context) { 16 | super(context); 17 | } 18 | 19 | public SurfaceViewContainer(@NonNull Context context, @Nullable AttributeSet attrs) { 20 | super(context, attrs); 21 | } 22 | 23 | public SurfaceViewContainer(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 24 | super(context, attrs, defStyleAttr); 25 | } 26 | 27 | @Override 28 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 29 | final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); 30 | final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); 31 | setMeasuredDimension(width, height); 32 | } 33 | 34 | @Override 35 | protected void onLayout(boolean changed, int l, int t, int r, int b) { 36 | if (changed && getChildCount() > 0) { 37 | layoutChild(r - l, b - t); 38 | } 39 | } 40 | 41 | private void layoutChild(int width, int height) { 42 | final View child = getChildAt(0); 43 | 44 | int previewWidth = width; 45 | int previewHeight = height; 46 | if (mPreviewSize != null) { 47 | previewWidth = mPreviewSize.getWidth(); 48 | previewHeight = mPreviewSize.getHeight(); 49 | } 50 | 51 | if (width * previewHeight > height * previewWidth) { 52 | final int scaledChildHeight = previewHeight * width / previewWidth; 53 | child.layout(0, (height - scaledChildHeight) / 2, width, (height + scaledChildHeight) / 2); 54 | } else { 55 | final int scaledChildWidth = previewWidth * height / previewHeight; 56 | child.layout((width - scaledChildWidth) / 2, 0, (width + scaledChildWidth) / 2, height); 57 | } 58 | } 59 | 60 | public void setPreviewSize(Size previewSize) { 61 | setPreviewSize(previewSize, mDisplayOrientation); 62 | } 63 | 64 | public void setPreviewSize(Size previewSize, int displayOrientation) { 65 | if (mDisplayOrientation == 0 || mDisplayOrientation == 180) { 66 | this.mPreviewSize = previewSize; 67 | } else if ((displayOrientation == 90 || displayOrientation == 270) && (mDisplayOrientation != 90 && mDisplayOrientation != 270)) { 68 | this.mPreviewSize = new Size(previewSize.getHeight(), previewSize.getWidth()); 69 | } 70 | 71 | if (getChildCount() > 0) { 72 | post(new Runnable() { 73 | @Override 74 | public void run() { 75 | layoutChild(getWidth(), getHeight()); 76 | } 77 | }); 78 | } 79 | } 80 | 81 | public void setDisplayOrientation(int displayOrientation) { 82 | if (mPreviewSize != null) { 83 | setPreviewSize(mPreviewSize, displayOrientation); 84 | } else { 85 | this.mDisplayOrientation = displayOrientation; 86 | } 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /camerakit/src/main/base/com/wonderkiln/camerakit/SurfaceViewPreview.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.annotation.TargetApi; 4 | import android.content.Context; 5 | import android.view.Surface; 6 | import android.view.SurfaceHolder; 7 | import android.view.SurfaceView; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | 11 | import com.wonderkiln.camerakit.core.R; 12 | 13 | public class SurfaceViewPreview extends PreviewImpl { 14 | 15 | private Context mContext; 16 | private ViewGroup mParent; 17 | private SurfaceViewContainer mContainer; 18 | private SurfaceView mSurfaceView; 19 | 20 | private int mDisplayOrientation; 21 | 22 | SurfaceViewPreview(final Context context, ViewGroup parent) { 23 | this.mContext = context; 24 | this.mParent = parent; 25 | 26 | final View view = View.inflate(context, R.layout.surface_view, parent); 27 | mContainer = view.findViewById(R.id.surface_view_container); 28 | mContainer.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 29 | @Override 30 | public void onLayoutChange(View view, int i, int i1, int i2, int i3, int i4, int i5, int i6, int i7) { 31 | setSize(mContainer.getWidth(), mContainer.getHeight()); 32 | } 33 | }); 34 | 35 | 36 | mSurfaceView = mContainer.findViewById(R.id.surface_view); 37 | 38 | final SurfaceHolder holder = mSurfaceView.getHolder(); 39 | 40 | holder.addCallback(new SurfaceHolder.Callback() { 41 | @Override 42 | public void surfaceCreated(SurfaceHolder holder) { 43 | } 44 | 45 | @Override 46 | public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 47 | if (isReady()) dispatchSurfaceChanged(); 48 | } 49 | 50 | @Override 51 | public void surfaceDestroyed(SurfaceHolder holder) { 52 | } 53 | }); 54 | } 55 | 56 | @Override 57 | SurfaceHolder getSurfaceHolder() { 58 | return mSurfaceView.getHolder(); 59 | } 60 | 61 | @Override 62 | Surface getSurface() { 63 | return getSurfaceHolder().getSurface(); 64 | } 65 | 66 | @Override 67 | View getView() { 68 | return mContainer; 69 | } 70 | 71 | @Override 72 | Class getOutputClass() { 73 | return SurfaceHolder.class; 74 | } 75 | 76 | @Override 77 | void setDisplayOrientation(int displayOrientation) { 78 | mDisplayOrientation = displayOrientation; 79 | mContainer.setDisplayOrientation(displayOrientation); 80 | } 81 | 82 | @Override 83 | boolean isReady() { 84 | return getPreviewWidth() != 0 && getPreviewHeight() != 0; 85 | } 86 | 87 | @Override 88 | float getX() { 89 | return mContainer.getChildAt(0).getX(); 90 | } 91 | 92 | @Override 93 | float getY() { 94 | return mContainer.getChildAt(0).getY(); 95 | } 96 | 97 | @TargetApi(15) 98 | @Override 99 | void setPreviewParameters(final int width, final int height, final int format) { 100 | super.setPreviewParameters(width, height, format); 101 | mContainer.setPreviewSize(new Size(width, height)); 102 | mContainer.post(new Runnable() { 103 | @Override 104 | public void run() { 105 | getSurfaceHolder().setFixedSize(getPreviewWidth(), getPreviewHeight()); 106 | } 107 | }); 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /camerakit/src/main/cpp/libjpeg/include/jinclude.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jinclude.h 3 | * 4 | * Copyright (C) 1991-1994, Thomas G. Lane. 5 | * This file is part of the Independent JPEG Group's software. 6 | * For conditions of distribution and use, see the accompanying README file. 7 | * 8 | * This file exists to provide a single place to fix any problems with 9 | * including the wrong system include files. (Common problems are taken 10 | * care of by the standard jconfig symbols, but on really weird systems 11 | * you may have to edit this file.) 12 | * 13 | * NOTE: this file is NOT intended to be included by applications using the 14 | * JPEG library. Most applications need only include jpeglib.h. 15 | */ 16 | 17 | 18 | /* Include auto-config file to find out which system include files we need. */ 19 | 20 | #include "jconfig.h" /* auto configuration options */ 21 | #define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */ 22 | 23 | /* 24 | * We need the NULL macro and size_t typedef. 25 | * On an ANSI-conforming system it is sufficient to include . 26 | * Otherwise, we get them from or ; we may have to 27 | * pull in as well. 28 | * Note that the core JPEG library does not require ; 29 | * only the default error handler and data source/destination modules do. 30 | * But we must pull it in because of the references to FILE in jpeglib.h. 31 | * You can remove those references if you want to compile without . 32 | */ 33 | 34 | #ifdef HAVE_STDDEF_H 35 | #include 36 | #endif 37 | 38 | #ifdef HAVE_STDLIB_H 39 | #include 40 | #endif 41 | 42 | #ifdef NEED_SYS_TYPES_H 43 | #include 44 | #endif 45 | 46 | #include 47 | 48 | /* 49 | * We need memory copying and zeroing functions, plus strncpy(). 50 | * ANSI and System V implementations declare these in . 51 | * BSD doesn't have the mem() functions, but it does have bcopy()/bzero(). 52 | * Some systems may declare memset and memcpy in . 53 | * 54 | * NOTE: we assume the size parameters to these functions are of type size_t. 55 | * Change the casts in these macros if not! 56 | */ 57 | 58 | #ifdef NEED_BSD_STRINGS 59 | 60 | #include 61 | #define MEMZERO(target,size) bzero((void *)(target), (size_t)(size)) 62 | #define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size)) 63 | 64 | #else /* not BSD, assume ANSI/SysV string lib */ 65 | 66 | #include 67 | #define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size)) 68 | #define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size)) 69 | 70 | #endif 71 | 72 | /* 73 | * In ANSI C, and indeed any rational implementation, size_t is also the 74 | * type returned by sizeof(). However, it seems there are some irrational 75 | * implementations out there, in which sizeof() returns an int even though 76 | * size_t is defined as long or unsigned long. To ensure consistent results 77 | * we always use this SIZEOF() macro in place of using sizeof() directly. 78 | */ 79 | 80 | #define SIZEOF(object) ((size_t) sizeof(object)) 81 | 82 | /* 83 | * The modules that use fread() and fwrite() always invoke them through 84 | * these macros. On some systems you may need to twiddle the argument casts. 85 | * CAUTION: argument order is different from underlying functions! 86 | */ 87 | 88 | #define JFREAD(file,buf,sizeofbuf) \ 89 | ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) 90 | #define JFWRITE(file,buf,sizeofbuf) \ 91 | ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) 92 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/preview/CameraSurfaceView.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.preview 2 | 3 | import android.content.Context 4 | import android.opengl.GLES20.glGenTextures 5 | import android.opengl.GLSurfaceView 6 | import android.os.Build 7 | import androidx.annotation.Keep 8 | import android.util.AttributeSet 9 | import javax.microedition.khronos.egl.EGLConfig 10 | import javax.microedition.khronos.opengles.GL10 11 | 12 | class CameraSurfaceView : GLSurfaceView, GLSurfaceView.Renderer { 13 | 14 | var cameraSurfaceTextureListener: CameraSurfaceTextureListener? = null 15 | private var cameraSurfaceTexture: CameraSurfaceTexture? = null 16 | 17 | constructor(context: Context) 18 | : super(context) 19 | 20 | constructor(context: Context, attributeSet: AttributeSet) 21 | : super(context, attributeSet) 22 | 23 | init { 24 | setEGLContextClientVersion(2) 25 | setRenderer(this) 26 | renderMode = RENDERMODE_WHEN_DIRTY 27 | 28 | nativeInit() 29 | } 30 | 31 | override fun onResume() { 32 | super.onResume() 33 | } 34 | 35 | override fun onPause() { 36 | super.onPause() 37 | } 38 | 39 | // GLSurfaceView.Renderer: 40 | 41 | override fun onSurfaceCreated(gl: GL10, config: EGLConfig) { 42 | genTextures { inputTexture, outputTexture -> 43 | cameraSurfaceTexture = CameraSurfaceTexture(inputTexture, outputTexture).apply { 44 | setOnFrameAvailableListener { requestRender() } 45 | cameraSurfaceTextureListener?.onSurfaceReady(this) 46 | } 47 | } 48 | 49 | nativeOnSurfaceCreated() 50 | } 51 | 52 | override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) { 53 | nativeOnSurfaceChanged(width, height) 54 | } 55 | 56 | override fun onDrawFrame(gl: GL10) { 57 | val cameraSurfaceTexture = cameraSurfaceTexture 58 | if (cameraSurfaceTexture != null) { 59 | nativeOnDrawFrame() 60 | 61 | cameraSurfaceTexture.updateTexImage() 62 | nativeDrawTexture(cameraSurfaceTexture.outputTexture, 63 | cameraSurfaceTexture.size.width, 64 | cameraSurfaceTexture.size.height) 65 | } 66 | } 67 | 68 | // Other: 69 | 70 | private fun genTextures(textureCallback: (inputTexture: Int, outputTexture: Int) -> Unit) { 71 | val textures = IntArray(2) 72 | glGenTextures(2, textures, 0) 73 | textureCallback(textures[0], textures[1]) 74 | } 75 | 76 | // --- 77 | 78 | @Keep 79 | override fun finalize() { 80 | super.finalize() 81 | try { 82 | nativeFinalize() 83 | } catch (e: Exception) { 84 | // ignore 85 | } 86 | } 87 | 88 | // --- 89 | 90 | @Keep 91 | private var nativeHandle: Long = 0L 92 | 93 | private external fun nativeInit() 94 | 95 | private external fun nativeOnSurfaceCreated() 96 | 97 | private external fun nativeOnSurfaceChanged(width: Int, height: Int) 98 | 99 | private external fun nativeOnDrawFrame() 100 | 101 | private external fun nativeDrawTexture(texture: Int, textureWidth: Int, textureHeight: Int) 102 | 103 | private external fun nativeFinalize() 104 | 105 | private external fun nativeRelease() 106 | 107 | companion object { 108 | 109 | init { 110 | if (Build.VERSION.SDK_INT <= 17) { 111 | System.loadLibrary("camerakit-core") 112 | } 113 | System.loadLibrary("camerakit") 114 | } 115 | 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/GestureLayout.java: -------------------------------------------------------------------------------- 1 | package com.camerakit; 2 | 3 | import android.content.Context; 4 | import androidx.annotation.NonNull; 5 | import androidx.annotation.Nullable; 6 | import android.util.AttributeSet; 7 | import android.view.GestureDetector; 8 | import android.view.MotionEvent; 9 | import android.view.ScaleGestureDetector; 10 | import android.widget.FrameLayout; 11 | 12 | public abstract class GestureLayout extends FrameLayout { 13 | 14 | private ScaleGestureDetector mScaleGestureDetector; 15 | private GestureDetector mGestureDetector; 16 | 17 | public GestureLayout(@NonNull Context context) { 18 | super(context); 19 | initialize(); 20 | } 21 | 22 | public GestureLayout(@NonNull Context context, @Nullable AttributeSet attrs) { 23 | super(context, attrs); 24 | initialize(); 25 | } 26 | 27 | public GestureLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 28 | super(context, attrs, defStyleAttr); 29 | initialize(); 30 | } 31 | 32 | private void initialize() { 33 | mScaleGestureDetector = new ScaleGestureDetector(getContext(), mScaleGestureListener); 34 | mGestureDetector = new GestureDetector(getContext(), mGestureListener); 35 | } 36 | 37 | @Override 38 | public boolean onTouchEvent(MotionEvent event) { 39 | mGestureDetector.onTouchEvent(event); 40 | mScaleGestureDetector.onTouchEvent(event); 41 | return true; 42 | } 43 | 44 | protected abstract void onTap(float x, float y); 45 | 46 | protected abstract void onLongTap(float x, float y); 47 | 48 | protected abstract void onDoubleTap(float x, float y); 49 | 50 | protected abstract void onPinch(float ds, float dsx, float dsy); 51 | 52 | public void performTap(float x, float y) { 53 | onTap(x, y); 54 | } 55 | 56 | public void performLongTap(float x, float y) { 57 | onLongTap(x, y); 58 | } 59 | 60 | public void performDoubleTap(float x, float y) { 61 | onDoubleTap(x, y); 62 | } 63 | 64 | public void performPinch(float dsx, float dsy) { 65 | float ds = (float) Math.sqrt((dsx * dsx) + (dsy * dsy)); 66 | onPinch(ds, dsx, dsy); 67 | } 68 | 69 | private GestureDetector.SimpleOnGestureListener mGestureListener = new GestureDetector.SimpleOnGestureListener() { 70 | @Override 71 | public boolean onSingleTapConfirmed(MotionEvent e) { 72 | performTap(e.getX() / (float) getWidth(), e.getY() / (float) getHeight()); 73 | return super.onSingleTapConfirmed(e); 74 | } 75 | 76 | @Override 77 | public boolean onDoubleTap(MotionEvent e) { 78 | performDoubleTap(e.getX() / (float) getWidth(), e.getY() / (float) getHeight()); 79 | return super.onDoubleTap(e); 80 | } 81 | 82 | @Override 83 | public void onLongPress(MotionEvent e) { 84 | performLongTap(e.getX() / (float) getWidth(), e.getY() / (float) getHeight()); 85 | } 86 | }; 87 | 88 | private ScaleGestureDetector.OnScaleGestureListener mScaleGestureListener = new ScaleGestureDetector.OnScaleGestureListener() { 89 | @Override 90 | public boolean onScale(ScaleGestureDetector detector) { 91 | float dsx = detector.getCurrentSpanX() - detector.getPreviousSpanX(); 92 | float dsy = detector.getCurrentSpanY() - detector.getPreviousSpanY(); 93 | performPinch(dsx, dsy); 94 | return true; 95 | } 96 | 97 | @Override 98 | public boolean onScaleBegin(ScaleGestureDetector detector) { 99 | return true; 100 | } 101 | 102 | @Override 103 | public void onScaleEnd(ScaleGestureDetector detector) { 104 | } 105 | }; 106 | 107 | } 108 | -------------------------------------------------------------------------------- /camerakit/src/main/utils/com/wonderkiln/camerakit/BitmapOperator.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import java.nio.ByteBuffer; 6 | 7 | public class BitmapOperator { 8 | 9 | private ByteBuffer handler; 10 | 11 | private BitmapOperator() { 12 | } 13 | 14 | public BitmapOperator(final byte[] bitmap) { 15 | storeBitmap(bitmap); 16 | } 17 | 18 | private void storeBitmap(final byte[] bitmap) { 19 | if (handler != null) freeBitmap(); 20 | handler = jniStoreBitmapData(bitmap); 21 | } 22 | 23 | public void rotateBitmap(int degrees) { 24 | if (handler == null) return; 25 | if (degrees == 90) jniRotateBitmapCw90(handler); 26 | else if (degrees == 180) jniRotateBitmap180(handler); 27 | else if (degrees == 270) jniRotateBitmapCcw90(handler); 28 | } 29 | 30 | public void cropBitmap(final int left, final int top, final int right, final int bottom) { 31 | if (handler == null) return; 32 | jniCropBitmap(handler, left, top, right, bottom); 33 | } 34 | 35 | public void flipBitmapHorizontal() { 36 | if (handler == null) return; 37 | jniFlipBitmapHorizontal(handler); 38 | } 39 | 40 | public void flipBitmapVertical() { 41 | if (handler == null) return; 42 | jniFlipBitmapVertical(handler); 43 | } 44 | 45 | public byte[] getJpeg(int quality) { 46 | if (handler == null) return null; 47 | return jniGetJpegData(handler, quality); 48 | } 49 | 50 | public byte[] getJpegAndFree(int quality) { 51 | final byte[] jpeg = getJpeg(quality); 52 | freeBitmap(); 53 | return jpeg; 54 | } 55 | 56 | public Bitmap getBitmap() { 57 | if (handler == null) return null; 58 | return jniGetBitmapFromStoredBitmapData(handler); 59 | } 60 | 61 | public Bitmap getBitmapAndFree() { 62 | final Bitmap bitmap = getBitmap(); 63 | freeBitmap(); 64 | return bitmap; 65 | } 66 | 67 | public int getWidth() { 68 | if (handler == null) return -1; 69 | return jniGetWidth(handler); 70 | } 71 | 72 | public int getHeight() { 73 | if (handler == null) return -1; 74 | return jniGetHeight(handler); 75 | } 76 | 77 | private void freeBitmap() { 78 | if (handler == null) return; 79 | jniFreeBitmapData(handler); 80 | handler = null; 81 | } 82 | 83 | @Override 84 | protected void finalize() throws Throwable { 85 | super.finalize(); 86 | if (handler == null) return; 87 | freeBitmap(); 88 | } 89 | 90 | static { 91 | System.loadLibrary("jpge"); 92 | System.loadLibrary("jpgd"); 93 | System.loadLibrary("JniYuvOperator"); 94 | System.loadLibrary("JniBitmapOperator"); 95 | } 96 | 97 | private native ByteBuffer jniStoreBitmapData(byte[] bitmap); 98 | 99 | private native Bitmap jniGetBitmapFromStoredBitmapData(ByteBuffer handler); 100 | 101 | private native byte[] jniGetJpegData(ByteBuffer handler, int quality); 102 | 103 | private native int jniGetWidth(ByteBuffer handler); 104 | 105 | private native int jniGetHeight(ByteBuffer handler); 106 | 107 | private native void jniFreeBitmapData(ByteBuffer handler); 108 | 109 | private native void jniRotateBitmapCcw90(ByteBuffer handler); 110 | 111 | private native void jniRotateBitmapCw90(ByteBuffer handler); 112 | 113 | private native void jniRotateBitmap180(ByteBuffer handler); 114 | 115 | private native void jniCropBitmap(ByteBuffer handler, final int left, final int top, final int right, final int bottom); 116 | 117 | private native void jniFlipBitmapHorizontal(ByteBuffer handler); 118 | 119 | private native void jniFlipBitmapVertical(ByteBuffer handler); 120 | 121 | } 122 | -------------------------------------------------------------------------------- /camerakit/src/main/utils/com/wonderkiln/camerakit/AspectRatio.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | import android.support.annotation.NonNull; 6 | import android.support.v4.util.SparseArrayCompat; 7 | 8 | public class AspectRatio implements Comparable, Parcelable { 9 | 10 | private final static SparseArrayCompat> sCache = new SparseArrayCompat<>(16); 11 | 12 | private final int mX; 13 | private final int mY; 14 | 15 | private AspectRatio(int x, int y) { 16 | mX = x; 17 | mY = y; 18 | } 19 | 20 | public int getX() { 21 | return mX; 22 | } 23 | 24 | public int getY() { 25 | return mY; 26 | } 27 | 28 | public boolean matches(Size size) { 29 | int gcd = gcd(size.getWidth(), size.getHeight()); 30 | int x = size.getWidth() / gcd; 31 | int y = size.getHeight() / gcd; 32 | return mX == x && mY == y; 33 | } 34 | 35 | @Override 36 | public boolean equals(Object o) { 37 | if (o == null) { 38 | return false; 39 | } 40 | if (this == o) { 41 | return true; 42 | } 43 | if (o instanceof AspectRatio) { 44 | AspectRatio ratio = (AspectRatio) o; 45 | return mX == ratio.mX && mY == ratio.mY; 46 | } 47 | return false; 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | return mX + ":" + mY; 53 | } 54 | 55 | public float toFloat() { 56 | return (float) mX / mY; 57 | } 58 | 59 | @Override 60 | public int hashCode() { 61 | return mY ^ ((mX << (Integer.SIZE / 2)) | (mX >>> (Integer.SIZE / 2))); 62 | } 63 | 64 | @Override 65 | public int compareTo(@NonNull AspectRatio another) { 66 | if (equals(another)) { 67 | return 0; 68 | } else if (toFloat() - another.toFloat() > 0) { 69 | return 1; 70 | } 71 | return -1; 72 | } 73 | 74 | public AspectRatio inverse() { 75 | return AspectRatio.of(mY, mX); 76 | } 77 | 78 | public static AspectRatio of(int x, int y) { 79 | int gcd = gcd(x, y); 80 | x /= gcd; 81 | y /= gcd; 82 | SparseArrayCompat arrayX = sCache.get(x); 83 | if (arrayX == null) { 84 | AspectRatio ratio = new AspectRatio(x, y); 85 | arrayX = new SparseArrayCompat<>(); 86 | arrayX.put(y, ratio); 87 | sCache.put(x, arrayX); 88 | return ratio; 89 | } else { 90 | AspectRatio ratio = arrayX.get(y); 91 | if (ratio == null) { 92 | ratio = new AspectRatio(x, y); 93 | arrayX.put(y, ratio); 94 | } 95 | return ratio; 96 | } 97 | } 98 | 99 | private static int gcd(int a, int b) { 100 | while (b != 0) { 101 | int c = b; 102 | b = a % b; 103 | a = c; 104 | } 105 | return a; 106 | } 107 | 108 | @Override 109 | public int describeContents() { 110 | return 0; 111 | } 112 | 113 | @Override 114 | public void writeToParcel(Parcel dest, int flags) { 115 | dest.writeInt(mX); 116 | dest.writeInt(mY); 117 | } 118 | 119 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 120 | 121 | @Override 122 | public AspectRatio createFromParcel(Parcel source) { 123 | int x = source.readInt(); 124 | int y = source.readInt(); 125 | return AspectRatio.of(x, y); 126 | } 127 | 128 | @Override 129 | public AspectRatio[] newArray(int size) { 130 | return new AspectRatio[size]; 131 | } 132 | 133 | }; 134 | 135 | } -------------------------------------------------------------------------------- /camerakit/src/main/cpp/libjpeg/include/config.h: -------------------------------------------------------------------------------- 1 | /* config.h. Generated from config.h.in by configure. */ 2 | /* config.h.in. Generated from configure.ac by autoheader. */ 3 | 4 | /* Build number */ 5 | #define BUILD "20110829" 6 | 7 | /* Support arithmetic encoding */ 8 | #define C_ARITH_CODING_SUPPORTED 1 9 | 10 | /* Support arithmetic decoding */ 11 | #define D_ARITH_CODING_SUPPORTED 1 12 | 13 | /* Define to 1 if you have the header file. */ 14 | #define HAVE_DLFCN_H 1 15 | 16 | /* Define to 1 if you have the header file. */ 17 | #define HAVE_INTTYPES_H 1 18 | 19 | /* Define to 1 if you have the header file. */ 20 | /* #undef HAVE_JNI_H */ 21 | 22 | /* Define to 1 if you have the `memcpy' function. */ 23 | #define HAVE_MEMCPY 1 24 | 25 | /* Define to 1 if you have the header file. */ 26 | #define HAVE_MEMORY_H 1 27 | 28 | /* Define to 1 if you have the `memset' function. */ 29 | #define HAVE_MEMSET 1 30 | 31 | /* Define if your compiler supports prototypes */ 32 | #define HAVE_PROTOTYPES 1 33 | 34 | /* Define to 1 if you have the header file. */ 35 | #define HAVE_STDDEF_H 1 36 | 37 | /* Define to 1 if you have the header file. */ 38 | #define HAVE_STDINT_H 1 39 | 40 | /* Define to 1 if you have the header file. */ 41 | #define HAVE_STDLIB_H 1 42 | 43 | /* Define to 1 if you have the header file. */ 44 | #define HAVE_STRINGS_H 1 45 | 46 | /* Define to 1 if you have the header file. */ 47 | #define HAVE_STRING_H 1 48 | 49 | /* Define to 1 if you have the header file. */ 50 | #define HAVE_SYS_STAT_H 1 51 | 52 | /* Define to 1 if you have the header file. */ 53 | #define HAVE_SYS_TYPES_H 1 54 | 55 | /* Define to 1 if you have the header file. */ 56 | #define HAVE_UNISTD_H 1 57 | 58 | /* Define to 1 if the system has the type `unsigned char'. */ 59 | #define HAVE_UNSIGNED_CHAR 1 60 | 61 | /* Define to 1 if the system has the type `unsigned short'. */ 62 | #define HAVE_UNSIGNED_SHORT 1 63 | 64 | /* Compiler does not support pointers to undefined structures. */ 65 | /* #undef INCOMPLETE_TYPES_BROKEN */ 66 | 67 | /* libjpeg API version */ 68 | #define JPEG_LIB_VERSION 62 69 | 70 | /* Define to the sub-directory in which libtool stores uninstalled libraries. 71 | */ 72 | #define LT_OBJDIR ".libs/" 73 | 74 | /* Define if you have BSD-like bzero and bcopy */ 75 | /* #undef NEED_BSD_STRINGS */ 76 | 77 | /* Define if you need short function names */ 78 | /* #undef NEED_SHORT_EXTERNAL_NAMES */ 79 | 80 | /* Define if you have sys/types.h */ 81 | #define NEED_SYS_TYPES_H 1 82 | 83 | /* Name of package */ 84 | #define PACKAGE "libjpeg-turbo" 85 | 86 | /* Define to the address where bug reports for this package should be sent. */ 87 | #define PACKAGE_BUGREPORT "" 88 | 89 | /* Define to the full name of this package. */ 90 | #define PACKAGE_NAME "libjpeg-turbo" 91 | 92 | /* Define to the full name and version of this package. */ 93 | #define PACKAGE_STRING "libjpeg-turbo 1.1.90" 94 | 95 | /* Define to the one symbol short name of this package. */ 96 | #define PACKAGE_TARNAME "libjpeg-turbo" 97 | 98 | /* Define to the home page for this package. */ 99 | #define PACKAGE_URL "" 100 | 101 | /* Define to the version of this package. */ 102 | #define PACKAGE_VERSION "1.1.90" 103 | 104 | /* Define if shift is unsigned */ 105 | /* #undef RIGHT_SHIFT_IS_UNSIGNED */ 106 | 107 | /* Define to 1 if you have the ANSI C header files. */ 108 | #define STDC_HEADERS 1 109 | 110 | /* Version number of package */ 111 | #define VERSION "1.1.90" 112 | 113 | /* Use accelerated SIMD routines. */ 114 | #define WITH_SIMD 1 115 | 116 | /* Define to 1 if type `char' is unsigned and you are not using gcc. */ 117 | #ifndef __CHAR_UNSIGNED__ 118 | /* # undef __CHAR_UNSIGNED__ */ 119 | #endif 120 | 121 | /* Define to empty if `const' does not conform to ANSI C. */ 122 | /* #undef const */ 123 | 124 | /* Define to `__inline__' or `__inline' if that's what the C compiler 125 | calls it, or to nothing if 'inline' is not supported under any name. */ 126 | #ifndef __cplusplus 127 | /* #undef inline */ 128 | #endif 129 | 130 | /* Define to `unsigned int' if does not define. */ 131 | /* #undef size_t */ 132 | -------------------------------------------------------------------------------- /camerakit/src/main/utils/com/wonderkiln/camerakit/DisplayOrientationDetector.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.content.Context; 4 | import android.util.SparseIntArray; 5 | import android.view.Display; 6 | import android.view.OrientationEventListener; 7 | import android.view.Surface; 8 | 9 | public abstract class DisplayOrientationDetector { 10 | 11 | private final OrientationEventListener mOrientationEventListener; 12 | 13 | static final SparseIntArray DISPLAY_ORIENTATIONS = new SparseIntArray(); 14 | 15 | static { 16 | DISPLAY_ORIENTATIONS.put(Surface.ROTATION_0, 0); 17 | DISPLAY_ORIENTATIONS.put(Surface.ROTATION_90, 90); 18 | DISPLAY_ORIENTATIONS.put(Surface.ROTATION_180, 180); 19 | DISPLAY_ORIENTATIONS.put(Surface.ROTATION_270, 270); 20 | } 21 | 22 | private Display mDisplay; 23 | 24 | private int mLastKnownDisplayOrientation = 0; 25 | private int mLastKnownDeviceOrientation = 0; 26 | 27 | public DisplayOrientationDetector(Context context) { 28 | mOrientationEventListener = new OrientationEventListener(context) { 29 | 30 | private int mLastKnownDisplayRotation = -1; 31 | 32 | @Override 33 | public void onOrientationChanged(int orientation) { 34 | if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN || mDisplay == null) { 35 | return; 36 | } 37 | 38 | boolean displayOrDeviceOrientationChanged = false; 39 | 40 | final int displayRotation = mDisplay.getRotation(); 41 | if (mLastKnownDisplayRotation != displayRotation) { 42 | mLastKnownDisplayRotation = displayRotation; 43 | displayOrDeviceOrientationChanged = true; 44 | } 45 | 46 | int deviceOrientation; 47 | if (orientation >= 60 && orientation <= 140) { 48 | // the mDisplay.getRotation stuff is flipped for 90 & 270 vs. deviceOrientation here. This keeps it consistent. 49 | deviceOrientation = 270; 50 | } else if (orientation >= 140 && orientation <= 220) { 51 | deviceOrientation = 180; 52 | } else if (orientation >= 220 && orientation <= 300) { 53 | // the mDisplay.getRotation stuff is flipped for 90 & 270 vs. deviceOrientation here. This keeps it consistent. 54 | deviceOrientation = 90; 55 | } else { 56 | deviceOrientation = 0; 57 | } 58 | 59 | if (mLastKnownDeviceOrientation != deviceOrientation) { 60 | mLastKnownDeviceOrientation = deviceOrientation; 61 | displayOrDeviceOrientationChanged = true; 62 | } 63 | 64 | if (displayOrDeviceOrientationChanged) { 65 | dispatchOnDisplayOrDeviceOrientationChanged(DISPLAY_ORIENTATIONS.get(displayRotation)); 66 | } 67 | } 68 | 69 | }; 70 | } 71 | 72 | public void enable(Display display) { 73 | mDisplay = display; 74 | mOrientationEventListener.enable(); 75 | dispatchOnDisplayOrDeviceOrientationChanged(DISPLAY_ORIENTATIONS.get(display.getRotation())); 76 | } 77 | 78 | public void disable() { 79 | mOrientationEventListener.disable(); 80 | mDisplay = null; 81 | } 82 | 83 | public int getLastKnownDisplayOrientation() { 84 | return mLastKnownDisplayOrientation; 85 | } 86 | 87 | void dispatchOnDisplayOrDeviceOrientationChanged(int displayOrientation) { 88 | mLastKnownDisplayOrientation = displayOrientation; 89 | 90 | // If we don't have accelerometers, we can't detect the device orientation. 91 | if (mOrientationEventListener.canDetectOrientation()) { 92 | onDisplayOrDeviceOrientationChanged(displayOrientation, mLastKnownDeviceOrientation); 93 | } else { 94 | onDisplayOrDeviceOrientationChanged(displayOrientation, displayOrientation); 95 | } 96 | } 97 | 98 | public abstract void onDisplayOrDeviceOrientationChanged(int displayOrientation, int deviceOrientation); 99 | 100 | } -------------------------------------------------------------------------------- /camerakit/src/main/events/com/wonderkiln/camerakit/EventDispatcher.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.os.Handler; 4 | import android.os.Looper; 5 | import android.support.annotation.NonNull; 6 | 7 | import java.lang.reflect.InvocationTargetException; 8 | import java.lang.reflect.Method; 9 | import java.util.ArrayList; 10 | import java.util.HashMap; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | class EventDispatcher { 15 | 16 | private Handler mainThreadHandler; 17 | 18 | private List listeners; 19 | private List bindings; 20 | 21 | public EventDispatcher() { 22 | this.mainThreadHandler = new Handler(Looper.getMainLooper()); 23 | this.listeners = new ArrayList<>(); 24 | this.bindings = new ArrayList<>(); 25 | } 26 | 27 | public void addListener(CameraKitEventListener listener) { 28 | this.listeners.add(listener); 29 | } 30 | 31 | public void addBinding(Object binding) { 32 | this.bindings.add(new BindingHandler(binding)); 33 | } 34 | 35 | public void dispatch(final CameraKitEvent event) { 36 | mainThreadHandler.post(new Runnable() { 37 | @Override 38 | public void run() { 39 | for (CameraKitEventListener listener : listeners) { 40 | listener.onEvent(event); 41 | if (event instanceof CameraKitError) listener.onError((CameraKitError) event); 42 | if (event instanceof CameraKitImage) listener.onImage((CameraKitImage) event); 43 | if (event instanceof CameraKitVideo) listener.onVideo((CameraKitVideo) event); 44 | } 45 | 46 | for (BindingHandler handler : bindings) { 47 | try { 48 | handler.dispatchEvent(event); 49 | } catch (Exception e) { 50 | e.printStackTrace(); 51 | } 52 | } 53 | } 54 | }); 55 | } 56 | 57 | private class BindingHandler { 58 | 59 | private Map> methods; 60 | 61 | public BindingHandler(@NonNull Object binding) { 62 | this.methods = new HashMap<>(); 63 | 64 | for (Method method : binding.getClass().getDeclaredMethods()) { 65 | if (method.isAnnotationPresent(OnCameraKitEvent.class)) { 66 | OnCameraKitEvent annotation = method.getAnnotation(OnCameraKitEvent.class); 67 | Class eventType = annotation.value(); 68 | addMethod(binding, method, eventType, methods); 69 | } 70 | } 71 | } 72 | 73 | private void addMethod(Object binding, Method method, Class type, Map> store) { 74 | if (!store.containsKey(type)) { 75 | store.put(type, new ArrayList()); 76 | } 77 | 78 | store.get(type).add(new MethodHolder(binding, method)); 79 | } 80 | 81 | public void dispatchEvent(@NonNull CameraKitEvent event) throws IllegalAccessException, InvocationTargetException { 82 | List baseMethods = methods.get(CameraKitEvent.class); 83 | if (baseMethods != null) { 84 | for (MethodHolder methodHolder : baseMethods) { 85 | methodHolder.getMethod().invoke(methodHolder.getBinding(), event); 86 | } 87 | } 88 | 89 | List targetMethods = methods.get(event.getClass()); 90 | if (targetMethods != null) { 91 | for (MethodHolder methodHolder : targetMethods) { 92 | methodHolder.getMethod().invoke(methodHolder.getBinding(), event); 93 | } 94 | } 95 | } 96 | 97 | private class MethodHolder { 98 | 99 | private Object binding; 100 | private Method method; 101 | 102 | public MethodHolder(Object binding, Method method) { 103 | this.binding = binding; 104 | this.method = method; 105 | } 106 | 107 | public Object getBinding() { 108 | return binding; 109 | } 110 | 111 | public Method getMethod() { 112 | return method; 113 | } 114 | 115 | } 116 | 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /camerakit/src/main/cpp/jni_camera_surface_texture.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | 5 | #include 6 | 7 | #include "camerakit/CameraSurfaceTexture.hpp" 8 | 9 | namespace camerakit { 10 | 11 | struct fields_t { 12 | jfieldID nativeHandle; 13 | }; 14 | 15 | static fields_t fields; 16 | 17 | // ---------------------------------------------------------------------------------------- 18 | 19 | static void CameraSurfaceTexture_setCameraSurfaceTexture(JNIEnv* env, jobject thiz, const CameraSurfaceTexture* cameraSurfaceTexture) { 20 | CameraSurfaceTexture* const currentObject 21 | = (CameraSurfaceTexture*) env->GetLongField(thiz, fields.nativeHandle); 22 | 23 | if (currentObject) { 24 | // TODO: stop old 25 | } 26 | 27 | env->SetLongField(thiz, fields.nativeHandle, reinterpret_cast(cameraSurfaceTexture)); 28 | } 29 | 30 | static CameraSurfaceTexture* CameraSurfaceTexture_getCameraSurfaceTexture(JNIEnv* env, jobject thiz) { 31 | long handle = (long) env->GetLongField(thiz, fields.nativeHandle); 32 | return reinterpret_cast(handle); 33 | } 34 | 35 | // ---------------------------------------------------------------------------------------- 36 | 37 | static void CameraSurfaceTexture_init(JNIEnv* env, jobject thiz, jint inputTexture, jint outputTexture) { 38 | CameraSurfaceTexture* cameraSurfaceTexture = new CameraSurfaceTexture(inputTexture, outputTexture); 39 | CameraSurfaceTexture_setCameraSurfaceTexture(env, thiz, cameraSurfaceTexture); 40 | 41 | jclass clazz = env->GetObjectClass(thiz); 42 | if (clazz == NULL) { 43 | // TODO: throw error 44 | return; 45 | } 46 | } 47 | 48 | static void CameraSurfaceTexture_setSize(JNIEnv* env, jobject thiz, jint width, jint height) { 49 | CameraSurfaceTexture* cameraSurfaceTexture = CameraSurfaceTexture_getCameraSurfaceTexture(env, thiz); 50 | cameraSurfaceTexture->setSize(width, height); 51 | } 52 | 53 | static void CameraSurfaceTexture_updateTexImage(JNIEnv* env, jobject thiz, jfloatArray transformMatrix, jfloatArray extraTransformMatrix) { 54 | CameraSurfaceTexture* cameraSurfaceTexture = CameraSurfaceTexture_getCameraSurfaceTexture(env, thiz); 55 | jfloat* matrix = env->GetFloatArrayElements(transformMatrix, 0); 56 | jfloat* extraMatrix = env->GetFloatArrayElements(extraTransformMatrix, 0); 57 | cameraSurfaceTexture->updateTexImage(matrix, extraMatrix); 58 | env->ReleaseFloatArrayElements(transformMatrix, matrix, 0); 59 | env->ReleaseFloatArrayElements(extraTransformMatrix, extraMatrix, 0); 60 | } 61 | 62 | static void CameraSurfaceTexture_finalize(JNIEnv* env, jobject thiz) { 63 | CameraSurfaceTexture* cameraSurfaceTexture = CameraSurfaceTexture_getCameraSurfaceTexture(env, thiz); 64 | 65 | // TODO: stop resources 66 | 67 | CameraSurfaceTexture_setCameraSurfaceTexture(env, thiz, 0); 68 | } 69 | 70 | 71 | static void CameraSurfaceTexture_release(JNIEnv* env, jobject thiz) { 72 | CameraSurfaceTexture* cameraSurfaceTexture = CameraSurfaceTexture_getCameraSurfaceTexture(env, thiz); 73 | } 74 | 75 | // ---------------------------------------------------------------------------------------- 76 | 77 | namespace jni { 78 | 79 | const char* const classPathName = "com/camerakit/preview/CameraSurfaceTexture"; 80 | 81 | static JNINativeMethod methods[] = { 82 | {"nativeInit", "(II)V", (void*) CameraSurfaceTexture_init}, 83 | {"nativeSetSize", "(II)V", (void*) CameraSurfaceTexture_setSize}, 84 | {"nativeUpdateTexImage", "([F[F)V", (void*) CameraSurfaceTexture_updateTexImage}, 85 | {"nativeFinalize", "()V", (void*) CameraSurfaceTexture_finalize}, 86 | {"nativeRelease", "()V", (void*) CameraSurfaceTexture_release} 87 | }; 88 | 89 | int register_CameraSurfaceTexture(JNIEnv* env) { 90 | jclass clazz = env->FindClass(classPathName); 91 | if (clazz == NULL) { 92 | // TODO: throw 93 | return -1; 94 | } 95 | 96 | jfieldID nativeHandle = env->GetFieldID(clazz, "nativeHandle", "J"); 97 | if (nativeHandle == NULL) { 98 | // TODO: throw 99 | return -1; 100 | } 101 | 102 | fields.nativeHandle = nativeHandle; 103 | 104 | int result = env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])); 105 | return result; 106 | } 107 | 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /camerakit/src/main/cpp/jni_camera_surface_view.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | 5 | #include 6 | 7 | #include "camerakit/CameraSurfaceView.hpp" 8 | 9 | namespace camerakit { 10 | 11 | struct fields_t { 12 | jfieldID nativeHandle; 13 | }; 14 | 15 | static fields_t fields; 16 | 17 | // ---------------------------------------------------------------------------------------- 18 | 19 | static void CameraSurfaceView_setCameraSurfaceView(JNIEnv* env, jobject thiz, const CameraSurfaceView* cameraSurfaceView) { 20 | CameraSurfaceView* const currentObject 21 | = (CameraSurfaceView*) env->GetLongField(thiz, fields.nativeHandle); 22 | 23 | if (currentObject) { 24 | // TODO: stop old 25 | } 26 | 27 | env->SetLongField(thiz, fields.nativeHandle, reinterpret_cast(cameraSurfaceView)); 28 | } 29 | 30 | static CameraSurfaceView* CameraSurfaceView_getCameraSurfaceView(JNIEnv* env, jobject thiz) { 31 | long handle = (long) env->GetLongField(thiz, fields.nativeHandle); 32 | return reinterpret_cast(handle); 33 | } 34 | 35 | // ---------------------------------------------------------------------------------------- 36 | 37 | static void CameraSurfaceView_init(JNIEnv* env, jobject thiz) { 38 | CameraSurfaceView* cameraSurfaceView = new CameraSurfaceView(); 39 | CameraSurfaceView_setCameraSurfaceView(env, thiz, cameraSurfaceView); 40 | 41 | jclass clazz = env->GetObjectClass(thiz); 42 | if (clazz == NULL) { 43 | // TODO: throw error 44 | return; 45 | } 46 | } 47 | 48 | static void CameraSurfaceView_onSurfaceCreated(JNIEnv* env, jobject thiz) { 49 | CameraSurfaceView* cameraSurfaceView = CameraSurfaceView_getCameraSurfaceView(env, thiz); 50 | cameraSurfaceView->onSurfaceCreated(); 51 | } 52 | 53 | static void CameraSurfaceView_onSurfaceChanged(JNIEnv* env, jobject thiz, jint width, jint height) { 54 | CameraSurfaceView* cameraSurfaceView = CameraSurfaceView_getCameraSurfaceView(env, thiz); 55 | cameraSurfaceView->onSurfaceChanged(width, height); 56 | } 57 | 58 | static void CameraSurfaceView_onDrawFrame(JNIEnv* env, jobject thiz) { 59 | CameraSurfaceView* cameraSurfaceView = CameraSurfaceView_getCameraSurfaceView(env, thiz); 60 | cameraSurfaceView->onDrawFrame(); 61 | } 62 | 63 | static void CameraSurfaceView_drawTexture(JNIEnv* env, jobject thiz, jint texture, jint textureWidth, jint textureHeight) { 64 | CameraSurfaceView* cameraSurfaceView = CameraSurfaceView_getCameraSurfaceView(env, thiz); 65 | cameraSurfaceView->drawTexture((GLuint) texture, textureWidth, textureHeight); 66 | } 67 | 68 | static void CameraSurfaceView_finalize(JNIEnv* env, jobject thiz) { 69 | CameraSurfaceView* cameraSurfaceView = CameraSurfaceView_getCameraSurfaceView(env, thiz); 70 | 71 | // TODO: stop resources 72 | 73 | CameraSurfaceView_setCameraSurfaceView(env, thiz, 0); 74 | } 75 | 76 | 77 | static void CameraSurfaceView_release(JNIEnv* env, jobject thiz) { 78 | CameraSurfaceView* cameraSurfaceView = CameraSurfaceView_getCameraSurfaceView(env, thiz); 79 | cameraSurfaceView->abandon(); 80 | } 81 | 82 | // ---------------------------------------------------------------------------------------- 83 | 84 | namespace jni { 85 | 86 | const char* const classPathName = "com/camerakit/preview/CameraSurfaceView"; 87 | 88 | static JNINativeMethod methods[] = { 89 | {"nativeInit", "()V", (void*) CameraSurfaceView_init}, 90 | {"nativeOnSurfaceCreated", "()V", (void*) CameraSurfaceView_onSurfaceCreated}, 91 | {"nativeOnSurfaceChanged", "(II)V", (void*) CameraSurfaceView_onSurfaceChanged}, 92 | {"nativeOnDrawFrame", "()V", (void*) CameraSurfaceView_onDrawFrame}, 93 | {"nativeDrawTexture", "(III)V", (void*) CameraSurfaceView_drawTexture}, 94 | {"nativeFinalize", "()V", (void*) CameraSurfaceView_finalize}, 95 | {"nativeRelease", "()V", (void*) CameraSurfaceView_release} 96 | }; 97 | 98 | int register_CameraSurfaceView(JNIEnv* env) { 99 | jclass clazz = env->FindClass(classPathName); 100 | if (clazz == NULL) { 101 | // TODO: throw 102 | return -1; 103 | } 104 | 105 | jfieldID nativeHandle = env->GetFieldID(clazz, "nativeHandle", "J"); 106 | if (nativeHandle == NULL) { 107 | // TODO: throw 108 | return -1; 109 | } 110 | 111 | fields.nativeHandle = nativeHandle; 112 | 113 | int result = env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])); 114 | return result; 115 | } 116 | 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /camerakit/src/main/cpp/libjpeg/include/jsimddct.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jsimddct.h 3 | * 4 | * Copyright 2009 Pierre Ossman for Cendio AB 5 | * 6 | * Based on the x86 SIMD extension for IJG JPEG library, 7 | * Copyright (C) 1999-2006, MIYASAKA Masaru. 8 | * For conditions of distribution and use, see copyright notice in jsimdext.inc 9 | * 10 | */ 11 | 12 | /* Short forms of external names for systems with brain-damaged linkers. */ 13 | 14 | #ifdef NEED_SHORT_EXTERNAL_NAMES 15 | #define jsimd_can_convsamp jSCanConv 16 | #define jsimd_can_convsamp_float jSCanConvF 17 | #define jsimd_convsamp jSConv 18 | #define jsimd_convsamp_float jSConvF 19 | #define jsimd_can_fdct_islow jSCanFDCTIS 20 | #define jsimd_can_fdct_ifast jSCanFDCTIF 21 | #define jsimd_can_fdct_float jSCanFDCTFl 22 | #define jsimd_fdct_islow jSFDCTIS 23 | #define jsimd_fdct_ifast jSFDCTIF 24 | #define jsimd_fdct_float jSFDCTFl 25 | #define jsimd_can_quantize jSCanQuant 26 | #define jsimd_can_quantize_float jSCanQuantF 27 | #define jsimd_quantize jSQuant 28 | #define jsimd_quantize_float jSQuantF 29 | #define jsimd_can_idct_2x2 jSCanIDCT22 30 | #define jsimd_can_idct_4x4 jSCanIDCT44 31 | #define jsimd_idct_2x2 jSIDCT22 32 | #define jsimd_idct_4x4 jSIDCT44 33 | #define jsimd_can_idct_islow jSCanIDCTIS 34 | #define jsimd_can_idct_ifast jSCanIDCTIF 35 | #define jsimd_can_idct_float jSCanIDCTFl 36 | #define jsimd_idct_islow jSIDCTIS 37 | #define jsimd_idct_ifast jSIDCTIF 38 | #define jsimd_idct_float jSIDCTFl 39 | #endif /* NEED_SHORT_EXTERNAL_NAMES */ 40 | 41 | EXTERN(int) jsimd_can_convsamp JPP((void)); 42 | EXTERN(int) jsimd_can_convsamp_float JPP((void)); 43 | 44 | EXTERN(void) jsimd_convsamp JPP((JSAMPARRAY sample_data, 45 | JDIMENSION start_col, 46 | DCTELEM * workspace)); 47 | EXTERN(void) jsimd_convsamp_float JPP((JSAMPARRAY sample_data, 48 | JDIMENSION start_col, 49 | FAST_FLOAT * workspace)); 50 | 51 | EXTERN(int) jsimd_can_fdct_islow JPP((void)); 52 | EXTERN(int) jsimd_can_fdct_ifast JPP((void)); 53 | EXTERN(int) jsimd_can_fdct_float JPP((void)); 54 | 55 | EXTERN(void) jsimd_fdct_islow JPP((DCTELEM * data)); 56 | EXTERN(void) jsimd_fdct_ifast JPP((DCTELEM * data)); 57 | EXTERN(void) jsimd_fdct_float JPP((FAST_FLOAT * data)); 58 | 59 | EXTERN(int) jsimd_can_quantize JPP((void)); 60 | EXTERN(int) jsimd_can_quantize_float JPP((void)); 61 | 62 | EXTERN(void) jsimd_quantize JPP((JCOEFPTR coef_block, 63 | DCTELEM * divisors, 64 | DCTELEM * workspace)); 65 | EXTERN(void) jsimd_quantize_float JPP((JCOEFPTR coef_block, 66 | FAST_FLOAT * divisors, 67 | FAST_FLOAT * workspace)); 68 | 69 | EXTERN(int) jsimd_can_idct_2x2 JPP((void)); 70 | EXTERN(int) jsimd_can_idct_4x4 JPP((void)); 71 | 72 | EXTERN(void) jsimd_idct_2x2 JPP((j_decompress_ptr cinfo, 73 | jpeg_component_info * compptr, 74 | JCOEFPTR coef_block, 75 | JSAMPARRAY output_buf, 76 | JDIMENSION output_col)); 77 | EXTERN(void) jsimd_idct_4x4 JPP((j_decompress_ptr cinfo, 78 | jpeg_component_info * compptr, 79 | JCOEFPTR coef_block, 80 | JSAMPARRAY output_buf, 81 | JDIMENSION output_col)); 82 | 83 | EXTERN(int) jsimd_can_idct_islow JPP((void)); 84 | EXTERN(int) jsimd_can_idct_ifast JPP((void)); 85 | EXTERN(int) jsimd_can_idct_float JPP((void)); 86 | 87 | EXTERN(void) jsimd_idct_islow JPP((j_decompress_ptr cinfo, 88 | jpeg_component_info * compptr, 89 | JCOEFPTR coef_block, 90 | JSAMPARRAY output_buf, 91 | JDIMENSION output_col)); 92 | EXTERN(void) jsimd_idct_ifast JPP((j_decompress_ptr cinfo, 93 | jpeg_component_info * compptr, 94 | JCOEFPTR coef_block, 95 | JSAMPARRAY output_buf, 96 | JDIMENSION output_col)); 97 | EXTERN(void) jsimd_idct_float JPP((j_decompress_ptr cinfo, 98 | jpeg_component_info * compptr, 99 | JCOEFPTR coef_block, 100 | JSAMPARRAY output_buf, 101 | JDIMENSION output_col)); 102 | 103 | -------------------------------------------------------------------------------- /.repo/gh-readme-infitting-logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle openCamera up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to openCamera the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /camerakit/src/main/cpp/libjpeg/include/cderror.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cderror.h 3 | * 4 | * Copyright (C) 1994-1997, Thomas G. Lane. 5 | * Modified 2009 by Guido Vollbeding. 6 | * This file is part of the Independent JPEG Group's software. 7 | * For conditions of distribution and use, see the accompanying README file. 8 | * 9 | * This file defines the error and message codes for the cjpeg/djpeg 10 | * applications. These strings are not needed as part of the JPEG library 11 | * proper. 12 | * Edit this file to add new codes, or to translate the message strings to 13 | * some other language. 14 | */ 15 | 16 | /* 17 | * To define the enum list of message codes, include this file without 18 | * defining macro JMESSAGE. To create a message string table, include it 19 | * again with a suitable JMESSAGE definition (see jerror.c for an example). 20 | */ 21 | #ifndef JMESSAGE 22 | #ifndef CDERROR_H 23 | #define CDERROR_H 24 | /* First time through, define the enum list */ 25 | #define JMAKE_ENUM_LIST 26 | #else 27 | /* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ 28 | #define JMESSAGE(code,string) 29 | #endif /* CDERROR_H */ 30 | #endif /* JMESSAGE */ 31 | 32 | #ifdef JMAKE_ENUM_LIST 33 | 34 | typedef enum { 35 | 36 | #define JMESSAGE(code,string) code , 37 | 38 | #endif /* JMAKE_ENUM_LIST */ 39 | 40 | JMESSAGE(JMSG_FIRSTADDONCODE=1000, NULL) /* Must be first entry! */ 41 | 42 | #ifdef BMP_SUPPORTED 43 | JMESSAGE(JERR_BMP_BADCMAP, "Unsupported BMP colormap format") 44 | JMESSAGE(JERR_BMP_BADDEPTH, "Only 8- and 24-bit BMP files are supported") 45 | JMESSAGE(JERR_BMP_BADHEADER, "Invalid BMP file: bad header length") 46 | JMESSAGE(JERR_BMP_BADPLANES, "Invalid BMP file: biPlanes not equal to 1") 47 | JMESSAGE(JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB") 48 | JMESSAGE(JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported") 49 | JMESSAGE(JERR_BMP_EMPTY, "Empty BMP image") 50 | JMESSAGE(JERR_BMP_NOT, "Not a BMP file - does not start with BM") 51 | JMESSAGE(JTRC_BMP, "%ux%u 24-bit BMP image") 52 | JMESSAGE(JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image") 53 | JMESSAGE(JTRC_BMP_OS2, "%ux%u 24-bit OS2 BMP image") 54 | JMESSAGE(JTRC_BMP_OS2_MAPPED, "%ux%u 8-bit colormapped OS2 BMP image") 55 | #endif /* BMP_SUPPORTED */ 56 | 57 | #ifdef GIF_SUPPORTED 58 | JMESSAGE(JERR_GIF_BUG, "GIF output got confused") 59 | JMESSAGE(JERR_GIF_CODESIZE, "Bogus GIF codesize %d") 60 | JMESSAGE(JERR_GIF_COLORSPACE, "GIF output must be grayscale or RGB") 61 | JMESSAGE(JERR_GIF_IMAGENOTFOUND, "Too few images in GIF file") 62 | JMESSAGE(JERR_GIF_NOT, "Not a GIF file") 63 | JMESSAGE(JTRC_GIF, "%ux%ux%d GIF image") 64 | JMESSAGE(JTRC_GIF_BADVERSION, 65 | "Warning: unexpected GIF version number '%c%c%c'") 66 | JMESSAGE(JTRC_GIF_EXTENSION, "Ignoring GIF extension block of type 0x%02x") 67 | JMESSAGE(JTRC_GIF_NONSQUARE, "Caution: nonsquare pixels in input") 68 | JMESSAGE(JWRN_GIF_BADDATA, "Corrupt data in GIF file") 69 | JMESSAGE(JWRN_GIF_CHAR, "Bogus char 0x%02x in GIF file, ignoring") 70 | JMESSAGE(JWRN_GIF_ENDCODE, "Premature end of GIF image") 71 | JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits") 72 | #endif /* GIF_SUPPORTED */ 73 | 74 | #ifdef PPM_SUPPORTED 75 | JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB") 76 | JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file") 77 | JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file") 78 | JMESSAGE(JTRC_PGM, "%ux%u PGM image") 79 | JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image") 80 | JMESSAGE(JTRC_PPM, "%ux%u PPM image") 81 | JMESSAGE(JTRC_PPM_TEXT, "%ux%u text PPM image") 82 | #endif /* PPM_SUPPORTED */ 83 | 84 | #ifdef RLE_SUPPORTED 85 | JMESSAGE(JERR_RLE_BADERROR, "Bogus error code from RLE library") 86 | JMESSAGE(JERR_RLE_COLORSPACE, "RLE output must be grayscale or RGB") 87 | JMESSAGE(JERR_RLE_DIMENSIONS, "Image dimensions (%ux%u) too large for RLE") 88 | JMESSAGE(JERR_RLE_EMPTY, "Empty RLE file") 89 | JMESSAGE(JERR_RLE_EOF, "Premature EOF in RLE header") 90 | JMESSAGE(JERR_RLE_MEM, "Insufficient memory for RLE header") 91 | JMESSAGE(JERR_RLE_NOT, "Not an RLE file") 92 | JMESSAGE(JERR_RLE_TOOMANYCHANNELS, "Cannot handle %d output channels for RLE") 93 | JMESSAGE(JERR_RLE_UNSUPPORTED, "Cannot handle this RLE setup") 94 | JMESSAGE(JTRC_RLE, "%ux%u full-color RLE file") 95 | JMESSAGE(JTRC_RLE_FULLMAP, "%ux%u full-color RLE file with map of length %d") 96 | JMESSAGE(JTRC_RLE_GRAY, "%ux%u grayscale RLE file") 97 | JMESSAGE(JTRC_RLE_MAPGRAY, "%ux%u grayscale RLE file with map of length %d") 98 | JMESSAGE(JTRC_RLE_MAPPED, "%ux%u colormapped RLE file with map of length %d") 99 | #endif /* RLE_SUPPORTED */ 100 | 101 | #ifdef TARGA_SUPPORTED 102 | JMESSAGE(JERR_TGA_BADCMAP, "Unsupported Targa colormap format") 103 | JMESSAGE(JERR_TGA_BADPARMS, "Invalid or unsupported Targa file") 104 | JMESSAGE(JERR_TGA_COLORSPACE, "Targa output must be grayscale or RGB") 105 | JMESSAGE(JTRC_TGA, "%ux%u RGB Targa image") 106 | JMESSAGE(JTRC_TGA_GRAY, "%ux%u grayscale Targa image") 107 | JMESSAGE(JTRC_TGA_MAPPED, "%ux%u colormapped Targa image") 108 | #else 109 | JMESSAGE(JERR_TGA_NOTCOMP, "Targa support was not compiled") 110 | #endif /* TARGA_SUPPORTED */ 111 | 112 | JMESSAGE(JERR_BAD_CMAP_FILE, 113 | "Color map file is invalid or of unsupported format") 114 | JMESSAGE(JERR_TOO_MANY_COLORS, 115 | "Output file format cannot handle %d colormap entries") 116 | JMESSAGE(JERR_UNGETC_FAILED, "ungetc failed") 117 | #ifdef TARGA_SUPPORTED 118 | JMESSAGE(JERR_UNKNOWN_FORMAT, 119 | "Unrecognized input file format --- perhaps you need -targa") 120 | #else 121 | JMESSAGE(JERR_UNKNOWN_FORMAT, "Unrecognized input file format") 122 | #endif 123 | JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format") 124 | 125 | #ifdef JMAKE_ENUM_LIST 126 | 127 | JMSG_LASTADDONCODE 128 | } ADDON_MESSAGE_CODE; 129 | 130 | #undef JMAKE_ENUM_LIST 131 | #endif /* JMAKE_ENUM_LIST */ 132 | 133 | /* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ 134 | #undef JMESSAGE 135 | -------------------------------------------------------------------------------- /camerakit/src/main/java/com/camerakit/api/camera1/Camera1.kt: -------------------------------------------------------------------------------- 1 | package com.camerakit.api.camera1 2 | 3 | import android.graphics.SurfaceTexture 4 | import android.hardware.Camera 5 | import com.camerakit.api.CameraApi 6 | import com.camerakit.api.CameraAttributes 7 | import com.camerakit.api.CameraEvents 8 | import com.camerakit.api.CameraHandler 9 | import com.camerakit.api.camera1.ext.getFlashes 10 | import com.camerakit.api.camera1.ext.getPhotoSizes 11 | import com.camerakit.api.camera1.ext.getPreviewSizes 12 | import com.camerakit.type.CameraFacing 13 | import com.camerakit.type.CameraFlash 14 | import com.camerakit.type.CameraSize 15 | 16 | class Camera1(eventsDelegate: CameraEvents) : 17 | CameraApi, CameraEvents by eventsDelegate { 18 | 19 | override val cameraHandler: CameraHandler = CameraHandler.get() 20 | 21 | private var camera: Camera? = null 22 | private var cameraAttributes: CameraAttributes? = null 23 | 24 | @Synchronized 25 | override fun open(facing: CameraFacing) { 26 | val cameraId = when (facing) { 27 | CameraFacing.BACK -> Camera.CameraInfo.CAMERA_FACING_BACK 28 | CameraFacing.FRONT -> Camera.CameraInfo.CAMERA_FACING_FRONT 29 | } 30 | 31 | val numberOfCameras = Camera.getNumberOfCameras() 32 | val cameraInfo = Camera.CameraInfo() 33 | for (i in 0 until numberOfCameras) { 34 | Camera.getCameraInfo(i, cameraInfo) 35 | if (cameraInfo.facing == cameraId) { 36 | val camera = Camera.open(i) 37 | val cameraParameters = camera.parameters 38 | val cameraAttributes = Attributes(cameraInfo, cameraParameters, facing) 39 | 40 | this.camera = camera 41 | this.cameraAttributes = cameraAttributes 42 | onCameraOpened(cameraAttributes) 43 | } 44 | } 45 | } 46 | 47 | @Synchronized 48 | override fun release() { 49 | camera?.release() 50 | camera = null 51 | cameraAttributes = null 52 | onCameraClosed() 53 | } 54 | 55 | @Synchronized 56 | override fun setPreviewOrientation(degrees: Int) { 57 | val camera = camera 58 | if (camera != null) { 59 | camera.setDisplayOrientation(degrees) 60 | } 61 | } 62 | 63 | @Synchronized 64 | override fun setPreviewSize(size: CameraSize) { 65 | val camera = camera 66 | if (camera != null) { 67 | val parameters = camera.parameters 68 | parameters.setPreviewSize(size.width, size.height) 69 | camera.parameters = parameters 70 | } 71 | } 72 | 73 | @Synchronized 74 | override fun startPreview(surfaceTexture: SurfaceTexture) { 75 | val camera = camera 76 | if (camera != null) { 77 | val parameters = camera.parameters 78 | if (parameters.supportedFocusModes != null && Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE in parameters.supportedFocusModes) { 79 | parameters.focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE 80 | camera.parameters = parameters 81 | } 82 | 83 | camera.setPreviewTexture(surfaceTexture) 84 | camera.setOneShotPreviewCallback { _, _ -> 85 | onPreviewStarted() 86 | } 87 | camera.startPreview() 88 | } 89 | } 90 | 91 | @Synchronized 92 | override fun stopPreview() { 93 | val camera = camera 94 | if (camera != null) { 95 | camera.stopPreview() 96 | onPreviewStopped() 97 | } 98 | } 99 | 100 | @Synchronized 101 | override fun setFlash(flash: CameraFlash) { 102 | val camera = camera 103 | if (camera != null) { 104 | val parameters = camera.parameters 105 | parameters.flashMode = when(flash) { 106 | CameraFlash.OFF -> Camera.Parameters.FLASH_MODE_OFF 107 | CameraFlash.ON -> Camera.Parameters.FLASH_MODE_ON 108 | CameraFlash.AUTO -> Camera.Parameters.FLASH_MODE_AUTO 109 | CameraFlash.TORCH -> Camera.Parameters.FLASH_MODE_TORCH 110 | } 111 | 112 | try { 113 | camera.parameters = parameters 114 | } catch (e: Exception) { 115 | // ignore failures for minor parameters like this for now 116 | } 117 | } 118 | } 119 | 120 | @Synchronized 121 | override fun setPhotoSize(size: CameraSize) { 122 | val camera = camera 123 | if (camera != null) { 124 | val parameters = camera.parameters 125 | parameters.setPictureSize(size.width, size.height) 126 | 127 | try { 128 | camera.parameters = parameters 129 | } catch (e: Exception) { 130 | // ignore failures for minor parameters like this for now 131 | } 132 | } 133 | } 134 | 135 | @Synchronized 136 | override fun capturePhoto(callback: (jpeg: ByteArray) -> Unit) { 137 | val camera = camera 138 | if (camera != null) { 139 | camera.takePicture(null, null) { data, _ -> 140 | callback(data) 141 | camera.startPreview() 142 | } 143 | } 144 | } 145 | 146 | private class Attributes(cameraInfo: Camera.CameraInfo, 147 | cameraParameters: Camera.Parameters, 148 | cameraFacing: CameraFacing) : CameraAttributes { 149 | 150 | override val facing: CameraFacing = cameraFacing 151 | 152 | override val sensorOrientation: Int = cameraInfo.orientation 153 | 154 | override val previewSizes: Array = cameraParameters.getPreviewSizes() 155 | 156 | override val photoSizes: Array = cameraParameters.getPhotoSizes() 157 | 158 | override val flashes: Array = cameraParameters.getFlashes() 159 | } 160 | 161 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | CameraKit Header 4 | 5 |

6 | 7 |

8 | 9 | Google Play Link 10 | 11 | 12 | Join Spectrum 13 | 14 | 15 | Buddy.Works 16 | 17 |

18 | 19 | CameraKit helps you add reliable camera to your app quickly. Our open source camera platform provides consistent capture results, service that scales, and endless camera possibilities. 20 | 21 | With CameraKit you are able to effortlessly do the following: 22 | 23 | - Image and video capture seamlessly working with the same preview session. 24 | - Automatic system permission handling. 25 | - Automatic preview scaling. 26 | - Create a `CameraView` of any size (not just presets!). 27 | - Automatic output cropping to match your `CameraView` bounds. 28 | - Multiple capture methods. 29 | - `METHOD_STANDARD`: an image captured normally using the camera APIs. 30 | - `METHOD_STILL`: a freeze frame of the `CameraView` preview (similar to SnapChat and Instagram) for devices with slower cameras. 31 | - `METHOD_SPEED`: automatic capture method determination based on measured speed. 32 | - Built-in continuous focus. 33 | - Built-in tap to focus. 34 | - Built-in pinch to zoom. 35 | 36 | ## Sponsored By 37 | Expensify 38 | Buddy.Works 39 | 40 | 41 | ## Trusted By 42 | InFitting 43 | GooseChase 44 | Alpha Apps 45 | Expensify 46 | 47 |   48 | 49 | # Get The Most From CameraKit 50 | There are currently two versions of CameraKit that we support, `v1.0.0-beta3.X` and `v0.13.X`. 51 | 52 | If photo is your only need, try out the latest and greatest CameraKit features with `v1.0.0-beta3.11`. Our `beta3.11` release does not yet support video, but that feature is coming! 53 | 54 | In the meantime, if your application requires video we recommend sticking with `v0.13.4`; the latest stable release with video implementation. 55 | 56 | 57 | | Use Case | Version | Notes | Documentation Link | 58 | | --- | --- | --- | --- | 59 | | Photo only | `v1.0.0-beta3.11` | The latest and greatest CameraKit has to offer. Video support coming soon! | [camerakit.io/docs/beta3.11](https://camerakit.io/docs?v=1.0.0-beta3.10) | 60 | | Photo and Video | `v0.13.4` | Stable build with full photo and video support | [camerakit.io/docs/0.13.4](https://camerakit.io/docs?v=0.13.2) | 61 | 62 | 63 | ## Documentation Site 64 | Setup instructions for `1.0.0-beta3.11` are below. To see the full documentation head over to our website, [camerakit.io/docs](https://camerakit.io/docs). 65 | 66 | 67 | ## Setup 68 | To include __CameraKit__ in your project, add the following to your `app` level `build.gradle`. 69 | ```java 70 | dependencies { 71 | implementation 'com.camerakit:camerakit:1.0.0-beta3.11' 72 | implementation 'com.camerakit:jpegkit:0.1.0' 73 | implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.0' 74 | implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.0' 75 | } 76 | ``` 77 | ## Usage 78 | Create a `CameraKitView` in your layout as follows: 79 | ``` 80 | 86 | app:camera_flash="auto" 87 | app:camera_facing="back" 88 | app:camera_focus="continuous" 89 | app:camera_permissions="camera" /> 90 | ``` 91 | 92 | Then create a new `CameraKitView` object in your `Activity` and override the following methods. 93 | ```java 94 | private CameraKitView cameraKitView; 95 | 96 | @Override 97 | protected void onCreate(Bundle savedInstanceState) { 98 | super.onCreate(savedInstanceState); 99 | setContentView(R.layout.activity_main); 100 | cameraKitView = findViewById(R.id.camera); 101 | } 102 | 103 | @Override 104 | protected void onStart() { 105 | super.onStart(); 106 | cameraKitView.onStart(); 107 | } 108 | 109 | @Override 110 | protected void onResume() { 111 | super.onResume(); 112 | cameraKitView.onResume(); 113 | } 114 | 115 | @Override 116 | protected void onPause() { 117 | cameraKitView.onPause(); 118 | super.onPause(); 119 | } 120 | 121 | @Override 122 | protected void onStop() { 123 | cameraKitView.onStop(); 124 | super.onStop(); 125 | } 126 | 127 | @Override 128 | public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 129 | super.onRequestPermissionsResult(requestCode, permissions, grantResults); 130 | cameraKitView.onRequestPermissionsResult(requestCode, permissions, grantResults); 131 | } 132 | ``` 133 | ## ProGuard 134 | If using ProGuard, add the following rules: 135 | ``` 136 | -dontwarn com.google.android.gms.** 137 | -keepclasseswithmembers class com.camerakit.preview.CameraSurfaceView { 138 | native ; 139 | } 140 | ``` 141 | 142 | ## License 143 | CameraKit is [MIT License](https://github.com/CameraKit/CameraKit-Android/blob/master/LICENSE) 144 | -------------------------------------------------------------------------------- /camerakit/src/main/utils/com/wonderkiln/camerakit/PostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.wonderkiln.camerakit; 2 | 3 | import android.graphics.Rect; 4 | import android.support.media.ExifInterface; 5 | 6 | import java.io.ByteArrayInputStream; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | 10 | import static com.wonderkiln.camerakit.CameraKit.Constants.FACING_FRONT; 11 | 12 | public class PostProcessor { 13 | 14 | private byte[] picture; 15 | private int jpegQuality; 16 | private int facing; 17 | private AspectRatio cropAspectRatio; 18 | 19 | public PostProcessor(byte[] picture) { 20 | this.picture = picture; 21 | } 22 | 23 | public void setJpegQuality(int jpegQuality) { 24 | this.jpegQuality = jpegQuality; 25 | } 26 | 27 | public void setFacing(int facing) { 28 | this.facing = facing; 29 | } 30 | 31 | public void setCropOutput(AspectRatio aspectRatio) { 32 | this.cropAspectRatio = aspectRatio; 33 | } 34 | 35 | public byte[] getJpeg() { 36 | JpegTransformer jpegTransformer = new JpegTransformer(picture); 37 | 38 | int width = jpegTransformer.getWidth(); 39 | int height = jpegTransformer.getHeight(); 40 | 41 | ExifPostProcessor exifPostProcessor = new ExifPostProcessor(picture); 42 | exifPostProcessor.apply(jpegTransformer); 43 | 44 | if (facing == FACING_FRONT) { 45 | jpegTransformer.flipHorizontal(); 46 | } 47 | 48 | if (cropAspectRatio != null) { 49 | int cropWidth = width; 50 | int cropHeight = height; 51 | if (exifPostProcessor.areDimensionsFlipped()) { 52 | cropWidth = height; 53 | cropHeight = width; 54 | } 55 | 56 | new CenterCrop(cropWidth, cropHeight, cropAspectRatio).apply(jpegTransformer); 57 | } 58 | 59 | return jpegTransformer.getJpeg(); 60 | 61 | } 62 | 63 | private static class ExifPostProcessor { 64 | 65 | private int orientation = ExifInterface.ORIENTATION_UNDEFINED; 66 | 67 | public ExifPostProcessor(byte[] picture) { 68 | try { 69 | orientation = getExifOrientation(new ByteArrayInputStream(picture)); 70 | } catch (IOException e) { 71 | e.printStackTrace(); 72 | } 73 | } 74 | 75 | public void apply(JpegTransformer transformer) { 76 | switch (orientation) { 77 | case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: 78 | transformer.flipHorizontal(); 79 | break; 80 | case ExifInterface.ORIENTATION_ROTATE_180: 81 | transformer.rotate(180); 82 | break; 83 | case ExifInterface.ORIENTATION_FLIP_VERTICAL: 84 | transformer.flipVertical(); 85 | break; 86 | case ExifInterface.ORIENTATION_TRANSPOSE: 87 | transformer.rotate(90); 88 | transformer.flipHorizontal(); 89 | break; 90 | case ExifInterface.ORIENTATION_ROTATE_90: 91 | transformer.rotate(90); 92 | break; 93 | case ExifInterface.ORIENTATION_TRANSVERSE: 94 | transformer.rotate(270); 95 | transformer.flipHorizontal(); 96 | break; 97 | case ExifInterface.ORIENTATION_ROTATE_270: 98 | transformer.rotate(90); 99 | break; 100 | case ExifInterface.ORIENTATION_NORMAL: 101 | case ExifInterface.ORIENTATION_UNDEFINED: 102 | break; 103 | } 104 | } 105 | 106 | public boolean areDimensionsFlipped() { 107 | switch (orientation) { 108 | case ExifInterface.ORIENTATION_TRANSPOSE: 109 | case ExifInterface.ORIENTATION_ROTATE_90: 110 | case ExifInterface.ORIENTATION_TRANSVERSE: 111 | case ExifInterface.ORIENTATION_ROTATE_270: 112 | return true; 113 | case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: 114 | case ExifInterface.ORIENTATION_ROTATE_180: 115 | case ExifInterface.ORIENTATION_FLIP_VERTICAL: 116 | case ExifInterface.ORIENTATION_NORMAL: 117 | case ExifInterface.ORIENTATION_UNDEFINED: 118 | return false; 119 | } 120 | 121 | return false; 122 | } 123 | 124 | private static int getExifOrientation(InputStream inputStream) throws IOException { 125 | ExifInterface exif = new ExifInterface(inputStream); 126 | return exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); 127 | } 128 | 129 | } 130 | 131 | private static class CenterCrop { 132 | 133 | private int width; 134 | private int height; 135 | private AspectRatio aspectRatio; 136 | 137 | public CenterCrop(int width, int height, AspectRatio aspectRatio) { 138 | this.width = width; 139 | this.height = height; 140 | this.aspectRatio = aspectRatio; 141 | } 142 | 143 | public void apply(JpegTransformer transformer) { 144 | Rect crop = getCrop(width, height, aspectRatio); 145 | transformer.crop(crop); 146 | } 147 | 148 | private static Rect getCrop(int currentWidth, int currentHeight, AspectRatio targetRatio) { 149 | AspectRatio currentRatio = AspectRatio.of(currentWidth, currentHeight); 150 | 151 | Rect crop; 152 | if (currentRatio.toFloat() > targetRatio.toFloat()) { 153 | int width = (int) (currentHeight * targetRatio.toFloat()); 154 | int widthOffset = (currentWidth - width) / 2; 155 | crop = new Rect(widthOffset, 0, currentWidth - widthOffset, currentHeight); 156 | } else { 157 | int height = (int) (currentWidth * targetRatio.inverse().toFloat()); 158 | int heightOffset = (currentHeight - height) / 2; 159 | crop = new Rect(0, heightOffset, currentWidth, currentHeight - heightOffset); 160 | } 161 | 162 | return crop; 163 | } 164 | 165 | } 166 | 167 | } 168 | --------------------------------------------------------------------------------