Commit 2a3a1658 authored by jinx's avatar jinx

'初始化'

parents
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/cordova.plugin.camera.iml" filepath="$PROJECT_DIR$/.idea/cordova.plugin.camera.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="ce9823c8-c749-4218-9165-fb0170b5369a" name="Default" comment="" />
<ignored path="$PROJECT_DIR$/.tmp/" />
<ignored path="$PROJECT_DIR$/temp/" />
<ignored path="$PROJECT_DIR$/tmp/" />
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="TRACKING_ENABLED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" />
<component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER" />
<component name="JsGulpfileManager">
<detection-done>true</detection-done>
<sorting>DEFINITION_ORDER</sorting>
</component>
<component name="ProjectFrameBounds">
<option name="x" value="327" />
<option name="y" value="2" />
<option name="width" value="1045" />
<option name="height" value="745" />
</component>
<component name="ProjectView">
<navigator currentView="ProjectPane" proportions="" version="1">
<flattenPackages />
<showMembers />
<showModules />
<showLibraryContents />
<hideEmptyPackages />
<abbreviatePackageNames />
<autoscrollToSource />
<autoscrollFromSource />
<sortByType />
<manualOrder />
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="Scope" />
<pane id="ProjectPane" />
<pane id="Scratches" />
</panes>
</component>
<component name="PropertiesComponent">
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="ShelveChangesManager" show_recycled="false">
<option name="remove_strategy" value="false" />
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="ce9823c8-c749-4218-9165-fb0170b5369a" name="Default" comment="" />
<created>1558687997996</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1558687997996</updated>
<workItem from="1558687999225" duration="18000" />
</task>
<servers />
</component>
<component name="TimeTrackingManager">
<option name="totallyTimeSpent" value="18000" />
</component>
<component name="ToolWindowManager">
<frame x="327" y="2" width="1045" height="745" extended-state="0" />
<layout>
<window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.24925521" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
<window_info id="Docker" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
</layout>
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="1" />
</component>
<component name="VcsContentAnnotationSettings">
<option name="myLimit" value="2678400000" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager />
<watches-manager />
</component>
</project>
\ No newline at end of file
function takePicture()
{
cordova.plugins.camera.takePicture({"isCorp":true},success , error);
}
isCorp : 是否裁剪
true 裁剪
false 不裁剪
function success(path)
{
path : 图片路径
}
function error(msg)
{
msg : 错误内容
}
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
id="cordova.plugin.camera" version="0.0.1">
<name>cameraPlugin</name>
<author>camera</author>
<description>camera</description>
<keywords>camera</keywords>
<license>Apache 2.0</license>
<js-module charset="utf-8" name="camera" src="www/camera.js">
<clobbers target="cordova.plugins.camera" />
</js-module>
<platform name="android">
<config-file parent="/*" target="res/xml/config.xml">
<feature name="camera">
<param name="android-package" value="com.cordova.camera.CameraPlugin"/>
</feature>
</config-file>
<source-file src="src/android/CameraPlugin.java" target-dir="src/com/cordova/camera"/>
<source-file src="src/android/util/DimensionUtil.java" target-dir="src/com/cordova/camera/util"/>
<source-file src="src/android/util/FileUtil.java" target-dir="src/com/cordova/camera/util"/>
<source-file src="src/android/util/IDUtil.java" target-dir="src/com/cordova/camera/util"/>
<source-file src="src/android/util/ImageUtil.java" target-dir="src/com/cordova/camera/util"/>
<source-file src="src/android/view/CameraActivity.java" target-dir="src/com/cordova/camera/view"/>
<source-file src="src/android/view/CameraControl.java" target-dir="src/com/cordova/camera/view"/>
<source-file src="src/android/view/CameraLayout.java" target-dir="src/com/cordova/camera/view"/>
<source-file src="src/android/view/CameraThreadPool.java" target-dir="src/com/cordova/camera/view"/>
<source-file src="src/android/view/CameraView.java" target-dir="src/com/cordova/camera/view"/>
<source-file src="src/android/view/ICameraControl.java" target-dir="src/com/cordova/camera/view"/>
<source-file src="src/android/view/MaskView.java" target-dir="src/com/cordova/camera/view"/>
<source-file src="src/android/view/PermissionCallback.java" target-dir="src/com/cordova/camera/view"/>
<source-file src="src/android/layout/activity_camera.xml" target-dir="res/layout"/>
<source-file src="src/android/layout/confirm_result.xml" target-dir="res/layout"/>
<source-file src="src/android/layout/take_picture.xml" target-dir="res/layout"/>
<source-file src="src/android/drawable/camera_switch.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable/cancel.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable/close.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable/confirm.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable/gallery.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable/hint_align_bank_card.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable/id_card_locator_front.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable/light_off.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable/light_on.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable/rotate.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable/take_photo_highlight.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable/take_photo_normal.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable/round_corner.xml" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable/take_photo_selector.xml" target-dir="res/drawable-hdpi"/>
<!--
<source-file src="src/android/lib/android-support-v4.jar" target-dir="libs/" />
-->
<framework src="com.android.support:support-v4:24.1.1+" />
<config-file target="res/values/styles.xml" parent="/resources">
<declare-styleable name="CameraLayout">
<attr name="contentView" format="reference"/>
<attr name="centerView" format="reference"/>
<attr name="leftDownView" format="reference"/>
<attr name="rightUpView" format="reference"/>
</declare-styleable>
</config-file>
<config-file parent="/manifest" target="AndroidManifest.xml">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera2.full" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
</config-file>
<config-file target="AndroidManifest.xml" parent="/manifest/application">
<activity
android:name="com.cordova.camera.view.CameraActivity"
android:configChanges="screenSize|orientation"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen" />
</config-file>
</platform>
</plugin>
package com.cordova.camera;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import com.cordova.camera.util.FileUtil;
import com.cordova.camera.view.CameraActivity;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Created by xiang.wang on 2017/4/14.
*/
public class CameraPlugin extends CordovaPlugin {
private static final String ACTION_TAKE_PICTURE = "takePicture";
private static final int REQUEST_CODE_CAMERA = 102;
private CallbackContext mCallbackContext;
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
boolean isCorp = true;
if(args != null && args.length() > 0){
JSONObject object = args.optJSONObject(0);
if(object != null){
isCorp = object.optBoolean("isCorp");
}
}
if(ACTION_TAKE_PICTURE.equals(action)){
Intent intent = new Intent(cordova.getActivity(), CameraActivity.class);
intent.putExtra(CameraActivity.KEY_OUTPUT_FILE_PATH, FileUtil.getSaveFile(cordova.getActivity()).getAbsolutePath());
intent.putExtra(CameraActivity.KEY_CONTENT_TYPE, CameraActivity.CONTENT_TYPE_ID_CARD_FRONT);
intent.putExtra("isCrop", isCorp);
cordova.startActivityForResult(CameraPlugin.this,intent, REQUEST_CODE_CAMERA);
}
mCallbackContext = callbackContext;
return true;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == REQUEST_CODE_CAMERA && resultCode == Activity.RESULT_OK) {
if (intent != null) {
String path = FileUtil.getSaveFile(cordova.getActivity()).getAbsolutePath();
if(mCallbackContext != null){
if(!path.isEmpty()){
mCallbackContext.success(path);
}else{
mCallbackContext.success("取消拍照");
}
}
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#000000" />
<corners android:radius="12dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 按压时 -->
<item android:drawable="@drawable/take_photo_highlight" android:state_pressed="true" />
<!-- 被选中时 -->
<item android:drawable="@drawable/take_photo_normal" android:state_selected="true" />
<!-- 被激活时 -->
<item android:drawable="@drawable/take_photo_normal" android:state_activated="true" />
<!-- 默认时 -->
<item android:drawable="@drawable/take_photo_normal" />
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/take_picture_container"
layout="@layout/take_picture"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include
android:id="@+id/confirm_result_container"
layout="@layout/confirm_result"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.cordova.camera.view.CameraLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentView="@+id/display_image_view"
app:leftDownView="@+id/cancel_button"
app:rightUpView="@+id/confirm_button">
<ImageView
android:id="@+id/display_image_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/id_card_locator_front" />
<ImageView
android:id="@+id/cancel_button"
android:layout_width="60dp"
android:layout_height="40dp"
android:layout_marginBottom="16dp"
android:layout_marginLeft="18dp"
android:layout_marginStart="18dp"
android:padding="12dp"
android:src="@drawable/cancel" />
<ImageView
android:id="@+id/confirm_button"
android:layout_width="60dp"
android:layout_height="40dp"
android:layout_marginEnd="18dp"
android:layout_marginRight="18dp"
android:layout_marginTop="16dp"
android:padding="12dp"
android:src="@drawable/confirm" />
</com.cordova.camera.view.CameraLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#000000">
<ImageView
android:id="@+id/iv_light_button"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginEnd="18dp"
android:layout_marginRight="18dp"
android:clickable="true"
android:padding="15dp"
android:paddingBottom="3dp"
android:src="@drawable/light_off"
tools:ignore="RtlHardcoded" />
</RelativeLayout>
<com.cordova.camera.view.CameraLayout
android:id="@+id/cameralayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:centerView="@+id/take_photo_button"
app:contentView="@+id/camera_view"
app:leftDownView="@+id/album_button"
app:rightUpView="@+id/camera_switch">
<com.cordova.camera.view.CameraView
android:id="@+id/camera_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/album_button"
android:layout_width="60dp"
android:layout_height="40dp"
android:layout_marginBottom="16dp"
android:layout_marginLeft="18dp"
android:layout_marginStart="18dp"
android:padding="12dp"
android:src="@drawable/cancel" />
<ImageView
android:id="@+id/take_photo_button"
android:layout_width="58dp"
android:layout_height="58dp"
android:background="@drawable/take_photo_selector"
android:clickable="true" />
<ImageView
android:id="@+id/camera_switch"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginEnd="18dp"
android:layout_marginRight="18dp"
android:layout_marginTop="16dp"
android:clickable="true"
android:padding="15dp"
android:paddingBottom="3dp"
android:src="@drawable/camera_switch" />
</com.cordova.camera.view.CameraLayout>
</LinearLayout>
package com.cordova.camera.util;
import android.content.res.Resources;
public class DimensionUtil {
public static int dpToPx(int dp) {
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
}
package com.cordova.camera.util;
import android.content.Context;
import java.io.File;
public class FileUtil {
public static File getSaveFile(Context context) {
File file = new File(context.getFilesDir(), "pic.jpg");
return file;
}
}
package com.cordova.camera.util;
import android.content.Context;
import java.lang.reflect.Field;
/**
* Created by USER on 2019/5/24.
*/
public class IDUtil {
public static int getIdByNameAndType(Context context,String type,String name){
return context.getResources().getIdentifier(name, type, context.getPackageName()) ;
}
/**
* 对于context.getResources().getIdentifier无法获取的数据,或者数组
* 资源反射值
* @paramcontext
* @param name
* @param type
* @return
*/
private static Object getResourceId(Context context,String name, String type) {
String className = context.getPackageName() +".R";
try {
Class cls = Class.forName(className);
for (Class childClass : cls.getClasses()) {
String simple = childClass.getSimpleName();
if (simple.equals(type)) {
for (Field field : childClass.getFields()) {
String fieldName = field.getName();
if (fieldName.equals(name)) {
System.out.println(fieldName);
return field.get(null);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
*context.getResources().getIdentifier无法获取到styleable的数据
* @paramcontext
* @param name
* @return
*/
public static int getStyleable(Context context, String name) {
return ((Integer)getResourceId(context, name,"styleable")).intValue();
}
/**
* 获取styleable的ID号数组
* @paramcontext
* @param name
* @return
*/
public static int[] getStyleableArray(Context context,String name) {
return (int[])getResourceId(context, name,"styleable");
}
}
package com.cordova.camera.util;
import android.graphics.BitmapFactory;
import android.media.ExifInterface;
import android.util.Log;
public class ImageUtil {
private static final String TAG = "CameraExif";
public static int exifToDegrees(int exifOrientation) {
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
return 90;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
return 180;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
return 270;
}
return 0;
}
// Returns the degrees in clockwise. Values are 0, 90, 180, or 270.
public static int getOrientation(byte[] jpeg) {
if (jpeg == null) {
return 0;
}
int offset = 0;
int length = 0;
// ISO/IEC 10918-1:1993(E)
while (offset + 3 < jpeg.length && (jpeg[offset++] & 0xFF) == 0xFF) {
int marker = jpeg[offset] & 0xFF;
// Check if the marker is a padding.
if (marker == 0xFF) {
continue;
}
offset++;
// Check if the marker is SOI or TEM.
if (marker == 0xD8 || marker == 0x01) {
continue;
}
// Check if the marker is EOI or SOS.
if (marker == 0xD9 || marker == 0xDA) {
break;
}
// Get the length and check if it is reasonable.
length = pack(jpeg, offset, 2, false);
if (length < 2 || offset + length > jpeg.length) {
Log.e(TAG, "Invalid length");
return 0;
}
// Break if the marker is EXIF in APP1.
if (marker == 0xE1 && length >= 8
&& pack(jpeg, offset + 2, 4, false) == 0x45786966
&& pack(jpeg, offset + 6, 2, false) == 0) {
offset += 8;
length -= 8;
break;
}
// Skip other markers.
offset += length;
length = 0;
}
// JEITA CP-3451 Exif Version 2.2
if (length > 8) {
// Identify the byte order.
int tag = pack(jpeg, offset, 4, false);
if (tag != 0x49492A00 && tag != 0x4D4D002A) {
Log.e(TAG, "Invalid byte order");
return 0;
}
boolean littleEndian = (tag == 0x49492A00);
// Get the offset and check if it is reasonable.
int count = pack(jpeg, offset + 4, 4, littleEndian) + 2;
if (count < 10 || count > length) {
Log.e(TAG, "Invalid offset");
return 0;
}
offset += count;
length -= count;
// Get the count and go through all the elements.
count = pack(jpeg, offset - 2, 2, littleEndian);
while (count-- > 0 && length >= 12) {
// Get the tag and check if it is orientation.
tag = pack(jpeg, offset, 2, littleEndian);
if (tag == 0x0112) {
// We do not really care about type and count, do we?
int orientation = pack(jpeg, offset + 8, 2, littleEndian);
switch (orientation) {
case 1:
return 0;
case 3:
return 180;
case 6:
return 90;
case 8:
return 270;
default:
return 0;
}
}
offset += 12;
length -= 12;
}
}
Log.i(TAG, "Orientation not found");
return 0;
}
private static int pack(byte[] bytes, int offset, int length,
boolean littleEndian) {
int step = 1;
if (littleEndian) {
offset += length - 1;
step = -1;
}
int value = 0;
while (length-- > 0) {
value = (value << 8) | (bytes[offset] & 0xFF);
offset += step;
}
return value;
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
}
<resources>
<declare-styleable name="CameraLayout">
<attr name="contentView" format="reference"/>
<attr name="centerView" format="reference"/>
<attr name="leftDownView" format="reference"/>
<attr name="rightUpView" format="reference"/>
</declare-styleable>
</resources>
This diff is collapsed.
This diff is collapsed.
package com.cordova.camera.view;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.cordova.camera.util.IDUtil;
public class CameraLayout extends FrameLayout {
public static int ORIENTATION_PORTRAIT = 0;
public static int ORIENTATION_HORIZONTAL = 1;
private int orientation = ORIENTATION_PORTRAIT;
private View contentView;
private View centerView;
private View leftDownView;
private View rightUpView;
private int contentViewId;
private int centerViewId;
private int leftDownViewId;
private int rightUpViewId;
private Context mContext;
public void setOrientation(int orientation) {
if (this.orientation == orientation) {
return;
}
this.orientation = orientation;
requestLayout();
}
public CameraLayout(Context context) {
super(context);
mContext = context;
}
public CameraLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
parseAttrs(attrs);
}
public CameraLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
parseAttrs(attrs);
}
{
setWillNotDraw(false);
}
private void parseAttrs(AttributeSet attrs) {
TypedArray a = getContext().getTheme().obtainStyledAttributes(
attrs,
IDUtil.getStyleableArray(mContext,"CameraLayout"),
0, 0);
try {
contentViewId = a.getResourceId(IDUtil.getStyleable(mContext,"CameraLayout_contentView"), -1);
centerViewId = a.getResourceId(IDUtil.getStyleable(mContext,"CameraLayout_centerView"), -1);
leftDownViewId = a.getResourceId(IDUtil.getStyleable(mContext,"CameraLayout_leftDownView"), -1);
rightUpViewId = a.getResourceId(IDUtil.getStyleable(mContext,"CameraLayout_rightUpView"), -1);
} finally {
a.recycle();
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
contentView = findViewById(contentViewId);
if (centerViewId != -1) {
centerView = findViewById(centerViewId);
}
leftDownView = findViewById(leftDownViewId);
rightUpView = findViewById(rightUpViewId);
}
private Rect backgroundRect = new Rect();
private Paint paint = new Paint();
{
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.argb(83, 0, 0, 0));
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int width = getWidth();
int height = getHeight();
int left;
int top;
ViewGroup.MarginLayoutParams leftDownViewLayoutParams = (MarginLayoutParams) leftDownView.getLayoutParams();
ViewGroup.MarginLayoutParams rightUpViewLayoutParams = (MarginLayoutParams) rightUpView.getLayoutParams();
if (r < b) {
int contentHeight = width * 7 / 5;
int heightLeft = height - contentHeight;
top = t - dpToPx(60);
contentView.layout(l, top, r, contentHeight);
backgroundRect.left = 0;
backgroundRect.top = contentHeight;
backgroundRect.right = width;
backgroundRect.bottom = height;
// layout centerView;
if (centerView != null) {
left = (width - centerView.getMeasuredWidth()) / 2;
top = contentHeight + (heightLeft - centerView.getMeasuredHeight()) / 2;
centerView
.layout(left, top, left + centerView.getMeasuredWidth(), top + centerView.getMeasuredHeight());
}
// layout leftDownView
left = leftDownViewLayoutParams.leftMargin;
top = contentHeight + (heightLeft - leftDownView.getMeasuredHeight()) / 2;
leftDownView
.layout(left, top, left + leftDownView.getMeasuredWidth(), top + leftDownView.getMeasuredHeight());
// layout rightUpView
left = width - rightUpView.getMeasuredWidth() - rightUpViewLayoutParams.rightMargin;
top = contentHeight + (heightLeft - rightUpView.getMeasuredHeight()) / 2;
rightUpView.layout(left, top, left + rightUpView.getMeasuredWidth(), top + rightUpView.getMeasuredHeight());
} else {
int contentWidth = height * 4 / 3;
int widthLeft = width - contentWidth;
contentView.layout(l, t, contentWidth, height);
backgroundRect.left = contentWidth;
backgroundRect.top = 0;
backgroundRect.right = width;
backgroundRect.bottom = height;
// layout centerView
if (centerView != null) {
left = contentWidth + (widthLeft - centerView.getMeasuredWidth()) / 2;
top = (height - centerView.getMeasuredHeight()) / 2;
centerView
.layout(left, top, left + centerView.getMeasuredWidth(), top + centerView.getMeasuredHeight());
}
// layout leftDownView
left = contentWidth + (widthLeft - leftDownView.getMeasuredWidth()) / 2;
top = height - leftDownView.getMeasuredHeight() - leftDownViewLayoutParams.bottomMargin;
leftDownView
.layout(left, top, left + leftDownView.getMeasuredWidth(), top + leftDownView.getMeasuredHeight());
// layout rightUpView
left = contentWidth + (widthLeft - rightUpView.getMeasuredWidth()) / 2;
top = rightUpViewLayoutParams.topMargin;
rightUpView.layout(left, top, left + rightUpView.getMeasuredWidth(), top + rightUpView.getMeasuredHeight());
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawRect(backgroundRect, paint);
}
public static int dpToPx(int dp) {
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
}
package com.cordova.camera.view;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CameraThreadPool {
static Timer timerFocus = null;
/*
* 对焦频率
*/
static final long cameraScanInterval = 2000;
/*
* 线程池大小
*/
private static int poolCount = Runtime.getRuntime().availableProcessors();
private static ExecutorService fixedThreadPool = Executors.newFixedThreadPool(poolCount);
/**
* 给线程池添加任务
*
* @param runnable 任务
*/
public static void execute(Runnable runnable) {
fixedThreadPool.execute(runnable);
}
/**
* 创建一个定时对焦的timer任务
*
* @param runnable 对焦代码
* @return Timer Timer对象,用来终止自动对焦
*/
public static Timer createAutoFocusTimerTask(final Runnable runnable) {
if (timerFocus != null) {
return timerFocus;
}
timerFocus = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
runnable.run();
}
};
timerFocus.scheduleAtFixedRate(task, 0, cameraScanInterval);
return timerFocus;
}
/**
* 终止自动对焦任务,实际调用了cancel方法并且清空对象
* 但是无法终止执行中的任务,需额外处理
*/
public static void cancelAutoFocusTimer() {
if (timerFocus != null) {
timerFocus.cancel();
timerFocus = null;
}
}
}
This diff is collapsed.
package com.cordova.camera.view;
import android.graphics.Rect;
import android.support.annotation.IntDef;
import android.view.View;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Desc:Android 5.0 相机的API发生很大的变化。些类屏蔽掉了 api的变化。相机的操作和功能,抽象剥离出来。
* Created by gyf on 2019/5/18.
*/
public interface ICameraControl {
/**
* 闪光灯关 {@link #setFlashMode(int)}
*/
int FLASH_MODE_OFF = 0;
/**
* 闪光灯开 {@link #setFlashMode(int)}
*/
int FLASH_MODE_TORCH = 1;
/**
* 闪光灯自动 {@link #setFlashMode(int)}
*/
int FLASH_MODE_AUTO = 2;
@IntDef({FLASH_MODE_TORCH, FLASH_MODE_OFF, FLASH_MODE_AUTO})
@interface FlashMode {
}
/**
* 照相回调。
*/
interface OnTakePictureCallback {
void onPictureTaken(byte[] data, int cameraId, boolean isCrop);
}
/**
* 设置本地质量控制回调,如果不设置则视为不扫描调用本地质量控制代码。
*/
void setDetectCallback(OnDetectPictureCallback callback);
/**
* 预览回调
*/
interface OnDetectPictureCallback {
int onDetect(byte[] data, int rotation);
}
/**
* 打开相机。
*/
void start();
/**
* 关闭相机
*/
void stop();
/**
* 切换摄像头
*/
void switchCamera();
void pause();
void resume();
/**
* 相机对应的预览视图。
* @return 预览视图
*/
View getDisplayView();
/**
* 看到的预览可能不是照片的全部。返回预览视图的全貌。
* @return 预览视图frame;
*/
Rect getPreviewFrame();
/**
* 拍照。结果在回调中获取。
* @param callback 拍照结果回调
* @param isCrop
*/
void takePicture(OnTakePictureCallback callback, boolean isCrop);
/**
* 设置权限回调,当手机没有拍照权限时,可在回调中获取。
* @param callback 权限回调
*/
void setPermissionCallback(PermissionCallback callback);
/**
* 设置水平方向
* @param displayOrientation 参数值见 {@link CameraView.Orientation}
*/
void setDisplayOrientation(@CameraView.Orientation int displayOrientation);
/**
* 获取到拍照权限时,调用些函数以继续。
*/
void refreshPermission();
/**
* 获取已经扫描成功,处理中
*/
AtomicBoolean getAbortingScan();
/**
* 设置闪光灯状态。
* @param flashMode {@link #FLASH_MODE_TORCH,#FLASH_MODE_OFF,#FLASH_MODE_AUTO}
*/
void setFlashMode(@FlashMode int flashMode);
/**
* 获取当前闪光灯状态
* @return 当前闪光灯状态 参见 {@link #setFlashMode(int)}
*/
@FlashMode
int getFlashMode();
/**
* 获取当前相机支持的闪光灯模式(是否支持Camera.Parameters.FLASH_MODE_TORCH模式)
*/
boolean isSupportFlashMode();
}
package com.cordova.camera.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.os.Build;
import android.support.annotation.IntDef;
import android.util.AttributeSet;
import android.view.View;
import java.io.File;
public class MaskView extends View {
public static final int MASK_TYPE_NONE = 0;
public static final int MASK_TYPE_ID_CARD_FRONT = 1;
@IntDef({MASK_TYPE_NONE, MASK_TYPE_ID_CARD_FRONT})
@interface MaskType {
}
public void setLineColor(int lineColor) {
this.lineColor = lineColor;
}
public void setMaskColor(int maskColor) {
this.maskColor = maskColor;
}
private int lineColor = Color.WHITE;
private int maskType = MASK_TYPE_ID_CARD_FRONT;
private int maskColor = Color.argb(100, 0, 0, 0);
private Paint eraser = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint pen = new Paint(Paint.ANTI_ALIAS_FLAG);
public Rect frame = new Rect();
public Rect getFrameRect() {
if (maskType == MASK_TYPE_NONE) {
return new Rect(0, 0, getWidth(), getHeight());
} else {
return new Rect(frame);
}
}
public Rect getFrameRectExtend() {
Rect rc = new Rect(frame);
int widthExtend = (int) ((frame.right - frame.left) * 0.02f);
int heightExtend = (int) ((frame.bottom - frame.top) * 0.02f);
rc.left -= widthExtend;
rc.right += widthExtend;
rc.top -= heightExtend;
rc.bottom += heightExtend;
return rc;
}
public void setMaskType(@MaskType int maskType) {
this.maskType = maskType;
switch (maskType) {
case MASK_TYPE_ID_CARD_FRONT:
break;
case MASK_TYPE_NONE:
default:
break;
}
invalidate();
}
public int getMaskType() {
return maskType;
}
public void setOrientation(@CameraView.Orientation int orientation) {
}
public MaskView(Context context) {
super(context);
init();
}
public MaskView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MaskView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
// locatorDrawable = ResourcesCompat.getDrawable(getResources(), R.drawable.id_card_locator_front, null);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (w > 0 && h > 0) {
float ratio = h > w ? 0.9f : 0.72f;
int width = (int) (w * ratio);
// int height = width * 400 / 620;
int height = (int) (width * (h - CameraLayout.dpToPx(60)) / w * 1f);
int left = (w - width) / 2;
int top = (h - height) / 2;
int right = width + left;
int bottom = height + top;
frame.left = left;
frame.top = top;
frame.right = right;
frame.bottom = bottom;
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect frame = this.frame;
int width = frame.width();
int height = frame.height();
int left = frame.left;
int top = frame.top;
int right = frame.right;
int bottom = frame.bottom;
canvas.drawColor(maskColor);
fillRectRound(left, top, right, bottom, 30, 30, false);
canvas.drawPath(path, pen);
canvas.drawPath(path, eraser);
}
private Path path = new Path();
private Path fillRectRound(float left, float top, float right, float bottom, float rx, float ry, boolean
conformToOriginalPost) {
path.reset();
if (rx < 0) {
rx = 0;
}
if (ry < 0) {
ry = 0;
}
float width = right - left;
float height = bottom - top;
if (rx > width / 2) {
rx = width / 2;
}
if (ry > height / 2) {
ry = height / 2;
}
float widthMinusCorners = (width - (2 * rx));
float heightMinusCorners = (height - (2 * ry));
path.moveTo(right, top + ry);
path.rQuadTo(0, -ry, -rx, -ry);
path.rLineTo(-widthMinusCorners, 0);
path.rQuadTo(-rx, 0, -rx, ry);
path.rLineTo(0, heightMinusCorners);
if (conformToOriginalPost) {
path.rLineTo(0, ry);
path.rLineTo(width, 0);
path.rLineTo(0, -ry);
} else {
path.rQuadTo(0, ry, rx, ry);
path.rLineTo(widthMinusCorners, 0);
path.rQuadTo(rx, 0, rx, -ry);
}
path.rLineTo(0, -heightMinusCorners);
path.close();
return path;
}
{
// 硬件加速不支持,图层混合。
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
pen.setColor(Color.WHITE);
pen.setStyle(Paint.Style.STROKE);
pen.setStrokeWidth(6);
eraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
private void capture(File file) {
}
}
package com.cordova.camera.view;
public interface PermissionCallback {
boolean onRequestPermission();
}
var exec = require('cordova/exec');
//拍照
exports.takePicture = function(arg, success, error) {
exec(success, error, "camera", "takePicture", [arg]);
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment