From d82d8a754078217e6bab2116f1665a9953677b5b Mon Sep 17 00:00:00 2001 From: Matthew Date: Tue, 22 Oct 2024 12:57:32 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=93=8D=E4=BD=9CUI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Application/build.gradle | 8 +- Application/lint-baseline.xml | 15 ++++ Application/src/main/AndroidManifest.xml | 43 ++++----- .../xypower/mppreview/Camera2RawFragment.java | 83 +++++++++++++----- .../com/xypower/mppreview/CameraActivity.java | 19 +++- .../com/xypower/mppreview/MainActivity.java | 54 ++++++++++++ .../src/main/res/drawable/ic_action_info.png | Bin 0 -> 1025 bytes Application/src/main/res/drawable/ic_back.xml | 5 ++ .../src/main/res/drawable/ic_launcher.png | Bin 0 -> 3400 bytes .../src/main/res/drawable/ic_take_photo.xml | 6 ++ Application/src/main/res/drawable/tile.9.png | Bin 0 -> 196 bytes .../layout-land/fragment_camera2_basic.xml | 67 +++++++------- .../src/main/res/layout/activity_main.xml | 59 +++++++++++++ gradle.properties | 2 + 14 files changed, 277 insertions(+), 84 deletions(-) create mode 100644 Application/lint-baseline.xml create mode 100644 Application/src/main/java/com/xypower/mppreview/MainActivity.java create mode 100644 Application/src/main/res/drawable/ic_action_info.png create mode 100644 Application/src/main/res/drawable/ic_back.xml create mode 100644 Application/src/main/res/drawable/ic_launcher.png create mode 100644 Application/src/main/res/drawable/ic_take_photo.xml create mode 100644 Application/src/main/res/drawable/tile.9.png create mode 100644 Application/src/main/res/layout/activity_main.xml create mode 100644 gradle.properties diff --git a/Application/build.gradle b/Application/build.gradle index 4277b77..265b3ae 100644 --- a/Application/build.gradle +++ b/Application/build.gradle @@ -20,8 +20,8 @@ repositories { } dependencies { - implementation 'com.android.support:appcompat-v7:28.0.0' - implementation 'com.android.support.constraint:constraint-layout:2.0.4' + implementation 'androidx.appcompat:appcompat:1.0.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' } // The sample build uses multiple directories to @@ -37,12 +37,10 @@ android { defaultConfig { minSdkVersion 24 + //noinspection ExpiredTargetSdkVersion targetSdkVersion 27 } - lint { - baseline = file("lint-baseline.xml") - } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 diff --git a/Application/lint-baseline.xml b/Application/lint-baseline.xml new file mode 100644 index 0000000..c290ffd --- /dev/null +++ b/Application/lint-baseline.xml @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/Application/src/main/AndroidManifest.xml b/Application/src/main/AndroidManifest.xml index 3441f94..d74b84c 100644 --- a/Application/src/main/AndroidManifest.xml +++ b/Application/src/main/AndroidManifest.xml @@ -1,47 +1,34 @@ - - - + - - - - + - - - + + + - + \ No newline at end of file diff --git a/Application/src/main/java/com/xypower/mppreview/Camera2RawFragment.java b/Application/src/main/java/com/xypower/mppreview/Camera2RawFragment.java index 92e479c..55628d2 100644 --- a/Application/src/main/java/com/xypower/mppreview/Camera2RawFragment.java +++ b/Application/src/main/java/com/xypower/mppreview/Camera2RawFragment.java @@ -24,12 +24,17 @@ import android.app.DialogFragment; import android.app.Fragment; import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.ImageFormat; import android.graphics.Matrix; import android.graphics.Point; import android.graphics.RectF; import android.graphics.SurfaceTexture; +import android.graphics.drawable.Drawable; import android.hardware.SensorManager; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCaptureSession; @@ -55,7 +60,7 @@ import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.SystemClock; -import android.support.v4.app.ActivityCompat; +import androidx.core.app.ActivityCompat; import android.text.TextUtils; import android.util.Log; import android.util.Size; @@ -66,6 +71,7 @@ import android.view.Surface; import android.view.TextureView; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageView; import android.widget.Switch; import android.widget.Toast; @@ -556,8 +562,12 @@ public class Camera2RawFragment extends Fragment } }; - public static Camera2RawFragment newInstance() { - return new Camera2RawFragment(); + public static Camera2RawFragment newInstance(final boolean hdr) { + + Camera2RawFragment fragment = new Camera2RawFragment(); + Bundle bundle = new Bundle(); + + return fragment; } @Override @@ -568,18 +578,22 @@ public class Camera2RawFragment extends Fragment @Override public void onViewCreated(final View view, Bundle savedInstanceState) { + + Resources resources = getResources(); + ImageView imageView = (ImageView)view.findViewById(R.id.picture); + imageView.setImageDrawable(resources.getDrawable(R.drawable.ic_take_photo)); + imageView = (ImageView)view.findViewById(R.id.backMain); + imageView.setImageDrawable(resources.getDrawable(R.drawable.ic_back)); + view.findViewById(R.id.picture).setOnClickListener(this); // view.findViewById(R.id.info).setOnClickListener(this); mTextureView = (AutoFitTextureView) view.findViewById(R.id.texture); - view.findViewById(R.id.hdr).setOnClickListener(new View.OnClickListener() { + view.findViewById(R.id.backMain).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - closeCamera(); - // stopBackgroundThread(); - // startBackgroundThread(); - openCamera(); + getActivity().finish(); } }); @@ -673,11 +687,9 @@ public class Camera2RawFragment extends Fragment return false; } - View rootView = getView(); - Switch hdrSwitch = (Switch)(rootView.findViewById(R.id.hdr)); + Intent intent = activity.getIntent(); + String expectedCameraId = Integer.toString(intent.getIntExtra("cameraId", 0)); - boolean hdrChecked = hdrSwitch.isChecked(); - final String expectedCameraId = hdrChecked ? "1" : "0"; try { // Find a CameraDevice that supports RAW captures, and configure state. for (String cameraId : manager.getCameraIdList()) { @@ -1017,7 +1029,7 @@ public class Camera2RawFragment extends Fragment activity.getWindowManager().getDefaultDisplay().getSize(displaySize); // Find the rotation of the device relative to the camera sensor's orientation. - int totalRotation = sensorToDeviceRotation(mCharacteristics, deviceRotation); + int totalRotation = sensorToDeviceRotation(mCharacteristics, deviceRotation, getRotationAdjustment()); // Swap the view dimensions for calculation as needed if they are rotated relative to // the sensor. @@ -1060,8 +1072,8 @@ public class Camera2RawFragment extends Fragment // cameras). int rotation = (mCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) ? - (360 + ORIENTATIONS.get(deviceRotation)) % 360 : - (360 - ORIENTATIONS.get(deviceRotation)) % 360; + (360 + ORIENTATIONS.get(deviceRotation + getRotationAdjustment() / 90)) % 360 : + (360 - ORIENTATIONS.get(deviceRotation + getRotationAdjustment() / 90)) % 360; Matrix matrix = new Matrix(); RectF viewRect = new RectF(0, 0, viewWidth, viewHeight); @@ -1183,7 +1195,7 @@ public class Camera2RawFragment extends Fragment // Set orientation. int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, - sensorToDeviceRotation(mCharacteristics, rotation)); + sensorToDeviceRotation(mCharacteristics, rotation, getRotationAdjustment())); // Set request tag to easily track results in callbacks. captureBuilder.setTag(mRequestCounter.getAndIncrement()); @@ -1329,20 +1341,32 @@ public class Camera2RawFragment extends Fragment int format = mImage.getFormat(); switch (format) { case ImageFormat.JPEG: { + ByteBuffer buffer = mImage.getPlanes()[0].getBuffer(); byte[] bytes = new byte[buffer.remaining()]; buffer.get(bytes); + FileOutputStream output = null; try { output = new FileOutputStream(mFile); - output.write(bytes); - success = true; + if (mCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) { + Bitmap bm = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, null); + Bitmap bm2 = flipBitmap(bm); + bm.recycle(); + success = bm2.compress(Bitmap.CompressFormat.JPEG, 95, output); + bm2.recycle(); + } else { + output.write(bytes); + success = true; + } } catch (IOException e) { e.printStackTrace(); } finally { mImage.close(); closeOutput(output); } + + break; } case ImageFormat.RAW_SENSOR: { @@ -1387,6 +1411,20 @@ public class Camera2RawFragment extends Fragment } } + private Bitmap flipBitmap(Bitmap bitmap) { + if (null == bitmap) { + return null; + } + int width = bitmap.getWidth(); + int height = bitmap.getHeight(); + Matrix m = new Matrix(); + m.postScale(-1, 1); //镜像水平翻转 + //m.postScale(1, -1); //镜像垂直翻转 + //m.postRotate(-90); //旋转-90度 + Bitmap new2 = Bitmap.createBitmap(bitmap, 0, 0, width, height, m, true); + return new2; + } + /** * Builder class for constructing {@link ImageSaver}s. *

@@ -1679,6 +1717,10 @@ public class Camera2RawFragment extends Fragment return Math.abs(aAspect - bAspect) <= ASPECT_RATIO_TOLERANCE; } + private int getRotationAdjustment() { + return TextUtils.equals(mCameraId, "1") ? 90 : 0; + } + /** * Rotation need to transform from the camera sensor orientation to the device's current * orientation. @@ -1689,11 +1731,11 @@ public class Camera2RawFragment extends Fragment * orientation. * @return the total rotation from the sensor orientation to the current device orientation. */ - private static int sensorToDeviceRotation(CameraCharacteristics c, int deviceOrientation) { + private static int sensorToDeviceRotation(CameraCharacteristics c, int deviceOrientation, int adjustment) { int sensorOrientation = c.get(CameraCharacteristics.SENSOR_ORIENTATION); // Get device orientation in degrees - deviceOrientation = ORIENTATIONS.get(deviceOrientation); + deviceOrientation = ORIENTATIONS.get((deviceOrientation + (adjustment / 90)) % ORIENTATIONS.size()); // Reverse device orientation for front-facing cameras if (c.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) { @@ -1702,6 +1744,7 @@ public class Camera2RawFragment extends Fragment // Calculate desired JPEG orientation relative to camera orientation to make // the image upright relative to the device orientation + return (sensorOrientation - deviceOrientation + 360) % 360; } diff --git a/Application/src/main/java/com/xypower/mppreview/CameraActivity.java b/Application/src/main/java/com/xypower/mppreview/CameraActivity.java index b1d7d1c..2abcbe2 100644 --- a/Application/src/main/java/com/xypower/mppreview/CameraActivity.java +++ b/Application/src/main/java/com/xypower/mppreview/CameraActivity.java @@ -18,21 +18,38 @@ package com.xypower.mppreview; import android.app.Activity; import android.os.Bundle; +import android.os.Handler; /** * Activity displaying a fragment that implements RAW photo captures. */ public class CameraActivity extends Activity { + Handler mHandler; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + + mHandler = new Handler(); setContentView(R.layout.activity_camera); if (null == savedInstanceState) { getFragmentManager().beginTransaction() - .replace(R.id.container, Camera2RawFragment.newInstance()) + .replace(R.id.container, Camera2RawFragment.newInstance(false)) .commit(); } } + + public void reopenFragment(final boolean hdr) { + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + getFragmentManager().beginTransaction() + .replace(R.id.container, Camera2RawFragment.newInstance(hdr)) + .commit(); + } + }, 0); + } + } diff --git a/Application/src/main/java/com/xypower/mppreview/MainActivity.java b/Application/src/main/java/com/xypower/mppreview/MainActivity.java new file mode 100644 index 0000000..257dacd --- /dev/null +++ b/Application/src/main/java/com/xypower/mppreview/MainActivity.java @@ -0,0 +1,54 @@ +package com.xypower.mppreview; + +import androidx.appcompat.app.AppCompatActivity; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.Switch; + +public class MainActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + ((Button)findViewById(R.id.channel1)).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + takePhoto(1); + } + }); + ((Button)findViewById(R.id.channel2)).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + takePhoto(2); + } + }); + ((Button)findViewById(R.id.channel3)).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + takePhoto(3); + } + }); + } + + protected void takePhoto(int channel) { + Switch hdrSwitch = (Switch) findViewById(R.id.hdr); + takePhoto(channel, hdrSwitch.isChecked()); + } + + protected void takePhoto(int channel, boolean hdr) { + int cameraId = channel - 1; + if (channel == 1 && hdr) { + cameraId = 1; + } + + Intent intent = new Intent(MainActivity.this, CameraActivity.class); + intent.putExtra("cameraId", cameraId); + startActivity(intent); + } +} \ No newline at end of file diff --git a/Application/src/main/res/drawable/ic_action_info.png b/Application/src/main/res/drawable/ic_action_info.png new file mode 100644 index 0000000000000000000000000000000000000000..32bd1aabcabb85ded957230533c00e735183a323 GIT binary patch literal 1025 zcmV+c1pfPpP)UDI7BaW>`N=bRlk|E2%^dB8hrR55et*8d|IcHT75QTnx&CD( z0RP&9B@dK5;L-x65HcIEwzf8qPN%o}e7;SFVXWg@h5G(8m&<)+eJL+59~&4LNV_!r zJh>+x2#3Sl{CdQ#bT}>ywQR&8iWzy)M+Q2ECY~)rE;`M%!}m*2L~T%H1|=Rs$~z==CdX= z48rmho`|t8O+~w5HL)!Nz)I((+8|_dYHF%o7dC|2VU#(bK)xovUn~V!!l|;d@(MD7 z$QZ@DcdfYA5&%`_FTxPs#yu+u3*fUT6H!Ve0B~QYkR&!V=On%G_H8SD!V&>jgyx}+Knp;|1FUifM$%zBVA`u=>gGED zq&&B>W-!17-PoZ8pu*>pbXb_S!SK5k1xd4g)>g@d_8I_WOpy-#W+|Ck0J!uB4ECW!8~_iN3BVZu zM3MEDkbUMBz)2YFhG8#Z(6Jl<2)`3DFCpta03QGM0E#<=iav?WWt8LK<;7mY% z3dxyac6RorXJyoBBXbJC^F}6?buvmg1pu84baGnrW|R;B`7n}q8^hfEjBmA(6>OMO zoz?C*-2~m-v6H8ldj5Q=dS1|RS_C^d&`6ihclsRfvKD*(IM9&9?Zd;vNh?iLJ4%?D z6zE845IW5TKT_s_(B@n7HxeEl>YLS3QbfqjMBxtg3WS%}Dot{PRD74`S|#s^V!qg# zPm9H_7TGYtTG>~N=HxEg%iV=#PR0&OU=>NZ*?hgu`!uJkZ!7kC-AcVK)E--XpioM< v;adXW#(G}RmOS8v72WVCdBBbJyrBIJ%ovMLu~&(q00000NkvXXu0mjfpn%#$ literal 0 HcmV?d00001 diff --git a/Application/src/main/res/drawable/ic_back.xml b/Application/src/main/res/drawable/ic_back.xml new file mode 100644 index 0000000..0dbdb8a --- /dev/null +++ b/Application/src/main/res/drawable/ic_back.xml @@ -0,0 +1,5 @@ + + + diff --git a/Application/src/main/res/drawable/ic_launcher.png b/Application/src/main/res/drawable/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..bba1165cf95f9f170112e78cf26991d561aa0438 GIT binary patch literal 3400 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 + + + diff --git a/Application/src/main/res/drawable/tile.9.png b/Application/src/main/res/drawable/tile.9.png new file mode 100644 index 0000000000000000000000000000000000000000..135862883e26eddce2b19db021adf62e10357ad0 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^d_XM3!3HF=W8NDADajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MQNTcjv*DdlK%YvZ_jLY;KT`zX$+@~lcus~rX(d9r71A} z`ThO9P5{3!^Gb##?W|{)7_*qnaG3jle#z^Ewh3!L+OJDkI - - - + + + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent"> -