SilkFX HDR demos
Test: this Bug: 266628247 Change-Id: Ib41de2de8634e03dd6f7f6b3909e4e109793fa31
This commit is contained in:
@@ -48,10 +48,7 @@ void DrawGainmapBitmap(SkCanvas* c, const sk_sp<const SkImage>& image, const SkR
|
||||
gainmapSrc.fRight *= sX;
|
||||
gainmapSrc.fTop *= sY;
|
||||
gainmapSrc.fBottom *= sY;
|
||||
// TODO: Temporary workaround for SkGainmapShader::Make not having a const variant
|
||||
sk_sp<SkImage> mutImage = sk_ref_sp(const_cast<SkImage*>(image.get()));
|
||||
sk_sp<SkImage> mutGainmap = sk_ref_sp(const_cast<SkImage*>(gainmapImage.get()));
|
||||
auto shader = SkGainmapShader::Make(mutImage, src, sampling, mutGainmap, gainmapSrc,
|
||||
auto shader = SkGainmapShader::Make(image, src, sampling, gainmapImage, gainmapSrc,
|
||||
sampling, gainmapInfo, dst, targetSdrHdrRatio,
|
||||
c->imageInfo().refColorSpace());
|
||||
gainmapPaint.setShader(shader);
|
||||
|
||||
@@ -25,13 +25,17 @@ package {
|
||||
|
||||
android_test {
|
||||
name: "SilkFX",
|
||||
srcs: ["**/*.java", "**/*.kt"],
|
||||
srcs: [
|
||||
"**/*.java",
|
||||
"**/*.kt",
|
||||
],
|
||||
platform_apis: true,
|
||||
certificate: "platform",
|
||||
static_libs: [
|
||||
static_libs: [
|
||||
"androidx.core_core",
|
||||
"androidx.appcompat_appcompat",
|
||||
"com.google.android.material_material",
|
||||
"androidx-constraintlayout_constraintlayout",
|
||||
"subsampling-scale-image-view",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -55,5 +55,15 @@
|
||||
android:exported="true">
|
||||
</activity>
|
||||
|
||||
<activity android:name=".app.HdrImageViewer"
|
||||
android:label="HDR Gainmap Image Viewer"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<data android:mimeType="image/*"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
BIN
tests/SilkFX/assets/gainmaps/cave.jpg
Normal file
BIN
tests/SilkFX/assets/gainmaps/cave.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.3 MiB |
23
tests/SilkFX/res/drawable-nodpi/blue_sweep_gradient.xml
Normal file
23
tests/SilkFX/res/drawable-nodpi/blue_sweep_gradient.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2023 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:startColor="#000000"
|
||||
android:endColor="#0000FF"
|
||||
android:angle="0"/>
|
||||
</shape>
|
||||
23
tests/SilkFX/res/drawable-nodpi/dark_gradient.xml
Normal file
23
tests/SilkFX/res/drawable-nodpi/dark_gradient.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2023 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:startColor="#000000"
|
||||
android:endColor="#181818"
|
||||
android:angle="0"/>
|
||||
</shape>
|
||||
23
tests/SilkFX/res/drawable-nodpi/green_sweep_gradient.xml
Normal file
23
tests/SilkFX/res/drawable-nodpi/green_sweep_gradient.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2023 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:startColor="#000000"
|
||||
android:endColor="#00FF00"
|
||||
android:angle="0"/>
|
||||
</shape>
|
||||
23
tests/SilkFX/res/drawable-nodpi/grey_sweep_gradient.xml
Normal file
23
tests/SilkFX/res/drawable-nodpi/grey_sweep_gradient.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2023 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:startColor="#000000"
|
||||
android:endColor="#FFFFFF"
|
||||
android:angle="0"/>
|
||||
</shape>
|
||||
23
tests/SilkFX/res/drawable-nodpi/light_gradient.xml
Normal file
23
tests/SilkFX/res/drawable-nodpi/light_gradient.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2023 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:startColor="#E8E8E8"
|
||||
android:endColor="#FFFFFF"
|
||||
android:angle="0"/>
|
||||
</shape>
|
||||
23
tests/SilkFX/res/drawable-nodpi/red_sweep_gradient.xml
Normal file
23
tests/SilkFX/res/drawable-nodpi/red_sweep_gradient.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2023 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:startColor="#000000"
|
||||
android:endColor="#FF0000"
|
||||
android:angle="0"/>
|
||||
</shape>
|
||||
20
tests/SilkFX/res/layout/color_grid.xml
Normal file
20
tests/SilkFX/res/layout/color_grid.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2020 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<com.android.test.silkfx.hdr.ColorGrid xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
@@ -24,16 +24,6 @@
|
||||
|
||||
<FrameLayout android:id="@+id/demo_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<com.android.test.silkfx.common.HDRIndicator
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:layout_margin="8dp" />
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
115
tests/SilkFX/res/layout/gainmap_decode_test.xml
Normal file
115
tests/SilkFX/res/layout/gainmap_decode_test.xml
Normal file
@@ -0,0 +1,115 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2023 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<com.android.test.silkfx.hdr.GainmapDecodeTest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/decode_full"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Decode full" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/decode_subsampled4"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Decode subsampled (1/4th)" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/decode_scaled66"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Decode scaled (66%)" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/decode_crop"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Decode croppedSquare" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/decode_cropScaled33"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Decode croppedSquare(33%)" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/source_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_weight="1">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sdr_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/sdr_source"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="8dp"
|
||||
android:scaleType="fitStart" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_weight="1">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/gainmap_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/gainmap"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="8dp"
|
||||
android:scaleType="fitStart" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.android.test.silkfx.hdr.GainmapDecodeTest>
|
||||
70
tests/SilkFX/res/layout/gainmap_image.xml
Normal file
70
tests/SilkFX/res/layout/gainmap_image.xml
Normal file
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2023 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<com.android.test.silkfx.hdr.GainmapImage xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/gainmap_image">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RadioGroup android:id="@+id/output_mode"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RadioButton android:id="@+id/output_sdr"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="SDR original" />
|
||||
|
||||
<RadioButton android:id="@+id/output_gainmap"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Gainmap" />
|
||||
|
||||
<RadioButton android:id="@+id/output_hdr"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="HDR (sdr+gainmap)" />
|
||||
</RadioGroup>
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/image_selection"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/error_msg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||
android:id="@+id/image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.android.test.silkfx.hdr.GainmapImage>
|
||||
53
tests/SilkFX/res/layout/gradient_sweep.xml
Normal file
53
tests/SilkFX/res/layout/gradient_sweep.xml
Normal file
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2023 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<View android:background="@drawable/dark_gradient"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<View android:background="@drawable/light_gradient"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<View android:background="@drawable/grey_sweep_gradient"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<View android:background="@drawable/red_sweep_gradient"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<View android:background="@drawable/green_sweep_gradient"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<View android:background="@drawable/blue_sweep_gradient"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
</LinearLayout>
|
||||
26
tests/SilkFX/res/layout/hdr_image_viewer.xml
Normal file
26
tests/SilkFX/res/layout/hdr_image_viewer.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2023 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/color_mode_controls" />
|
||||
<include layout="@layout/gainmap_image" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -26,6 +26,7 @@ import android.widget.BaseExpandableListAdapter
|
||||
import android.widget.ExpandableListView
|
||||
import android.widget.TextView
|
||||
import com.android.test.silkfx.app.CommonDemoActivity
|
||||
import com.android.test.silkfx.app.EXTRA_COMMON_CONTROLS
|
||||
import com.android.test.silkfx.app.EXTRA_LAYOUT
|
||||
import com.android.test.silkfx.app.EXTRA_TITLE
|
||||
import com.android.test.silkfx.hdr.GlowActivity
|
||||
@@ -37,10 +38,11 @@ class Demo(val name: String, val makeIntent: (Context) -> Intent) {
|
||||
constructor(name: String, activity: KClass<out Activity>) : this(name, { context ->
|
||||
Intent(context, activity.java)
|
||||
})
|
||||
constructor(name: String, layout: Int) : this(name, { context ->
|
||||
constructor(name: String, layout: Int, commonControls: Boolean = true) : this(name, { context ->
|
||||
Intent(context, CommonDemoActivity::class.java).apply {
|
||||
putExtra(EXTRA_LAYOUT, layout)
|
||||
putExtra(EXTRA_TITLE, name)
|
||||
putExtra(EXTRA_COMMON_CONTROLS, commonControls)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -49,7 +51,11 @@ data class DemoGroup(val groupName: String, val demos: List<Demo>)
|
||||
private val AllDemos = listOf(
|
||||
DemoGroup("HDR", listOf(
|
||||
Demo("Glow", GlowActivity::class),
|
||||
Demo("Blingy Notifications", R.layout.bling_notifications)
|
||||
Demo("Blingy Notifications", R.layout.bling_notifications),
|
||||
Demo("Color Grid", R.layout.color_grid),
|
||||
Demo("Gradient Sweep", R.layout.gradient_sweep),
|
||||
Demo("Gainmap Image", R.layout.gainmap_image),
|
||||
Demo("Gainmap Decode Test", R.layout.gainmap_decode_test, commonControls = false)
|
||||
)),
|
||||
DemoGroup("Materials", listOf(
|
||||
Demo("Glass", GlassActivity::class),
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.view.LayoutInflater
|
||||
|
||||
const val EXTRA_LAYOUT = "layout"
|
||||
const val EXTRA_TITLE = "title"
|
||||
const val EXTRA_COMMON_CONTROLS = "common_controls"
|
||||
|
||||
class CommonDemoActivity : BaseDemoActivity() {
|
||||
|
||||
@@ -38,8 +39,13 @@ class CommonDemoActivity : BaseDemoActivity() {
|
||||
val title = extras.getString(EXTRA_TITLE, "SilkFX")
|
||||
window.setTitle(title)
|
||||
|
||||
setContentView(R.layout.common_base)
|
||||
if (extras.getBoolean(EXTRA_COMMON_CONTROLS, true)) {
|
||||
setContentView(R.layout.common_base)
|
||||
LayoutInflater.from(this).inflate(layout, findViewById(R.id.demo_container), true)
|
||||
} else {
|
||||
setContentView(layout)
|
||||
}
|
||||
|
||||
actionBar?.title = title
|
||||
LayoutInflater.from(this).inflate(layout, findViewById(R.id.demo_container), true)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.test.silkfx.app
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.ImageDecoder
|
||||
import android.os.Bundle
|
||||
import com.android.test.silkfx.R
|
||||
import com.android.test.silkfx.hdr.GainmapImage
|
||||
|
||||
class HdrImageViewer : BaseDemoActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.hdr_image_viewer)
|
||||
|
||||
val intent = this.intent ?: return finish()
|
||||
if (Intent.ACTION_VIEW != intent.action) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
||||
val data = intent.data ?: return finish()
|
||||
|
||||
val source = ImageDecoder.createSource(contentResolver, data)
|
||||
findViewById<GainmapImage>(R.id.gainmap_image)!!.setImageSource(source)
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,11 @@ import android.util.AttributeSet
|
||||
import android.view.View
|
||||
|
||||
open class BaseDrawingView : View {
|
||||
val sRGB = ColorSpace.get(ColorSpace.Named.SRGB)
|
||||
val displayP3 = ColorSpace.get(ColorSpace.Named.DISPLAY_P3)
|
||||
val scRGB = ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB)
|
||||
val bt2020 = ColorSpace.get(ColorSpace.Named.BT2020)
|
||||
val bt2020_pq = ColorSpace.get(ColorSpace.Named.BT2020_PQ)
|
||||
val lab = ColorSpace.get(ColorSpace.Named.CIE_LAB)
|
||||
|
||||
val density: Float
|
||||
|
||||
77
tests/SilkFX/src/com/android/test/silkfx/hdr/ColorGrid.kt
Normal file
77
tests/SilkFX/src/com/android/test/silkfx/hdr/ColorGrid.kt
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.test.silkfx.hdr
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.ColorSpace
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Rect
|
||||
import android.util.AttributeSet
|
||||
import com.android.test.silkfx.common.BaseDrawingView
|
||||
|
||||
class ColorGrid(context: Context, attrs: AttributeSet?) : BaseDrawingView(context, attrs) {
|
||||
|
||||
init {
|
||||
isClickable = true
|
||||
setOnClickListener {
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
fun toMaxColor(color: Int, colorspace: ColorSpace): Long {
|
||||
val red = (Color.red(color) / 255f) * colorspace.getMaxValue(0)
|
||||
val green = (Color.green(color) / 255f) * colorspace.getMaxValue(1)
|
||||
val blue = (Color.blue(color) / 255f) * colorspace.getMaxValue(2)
|
||||
val alpha = Color.alpha(color) / 255f
|
||||
return Color.pack(red, green, blue, alpha, colorspace)
|
||||
}
|
||||
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
super.onDraw(canvas)
|
||||
|
||||
val paint = Paint()
|
||||
paint.isDither = true
|
||||
paint.isAntiAlias = true
|
||||
paint.textSize = 18.dp()
|
||||
paint.textAlign = Paint.Align.LEFT
|
||||
|
||||
val labels = arrayOf("sRGB", "Display P3", "BT2020_PQ", "scRGB(max)")
|
||||
val colorSpaces = arrayOf(sRGB, displayP3, bt2020_pq, scRGB)
|
||||
|
||||
val colWidth = width / colorSpaces.size.toFloat()
|
||||
val rowHeight = minOf((height - 20.dp()) / 4f, colWidth)
|
||||
|
||||
val dest = Rect(0, 0, rowHeight.toInt(), colWidth.toInt())
|
||||
|
||||
for (colIndex in labels.indices) {
|
||||
canvas.save()
|
||||
canvas.translate(colIndex * colWidth, 20.dp())
|
||||
|
||||
paint.color = Color.WHITE
|
||||
canvas.drawText(labels[colIndex], 0f, 1f, paint)
|
||||
|
||||
arrayOf(Color.WHITE, Color.RED, Color.BLUE, Color.GREEN).forEach {
|
||||
paint.setColor(toMaxColor(it, colorSpaces[colIndex]))
|
||||
canvas.drawRect(dest, paint)
|
||||
canvas.translate(0f, rowHeight)
|
||||
}
|
||||
canvas.restore()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.test.silkfx.hdr
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.ImageDecoder
|
||||
import android.graphics.Rect
|
||||
import android.util.AttributeSet
|
||||
import android.widget.Button
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.android.test.silkfx.R
|
||||
|
||||
enum class DecodeMode {
|
||||
Full,
|
||||
Subsampled4,
|
||||
Scaled66,
|
||||
CropedSquared,
|
||||
CropedSquaredScaled33
|
||||
}
|
||||
|
||||
class GainmapDecodeTest(context: Context, attrs: AttributeSet?) : LinearLayout(context, attrs) {
|
||||
|
||||
private fun decode(mode: DecodeMode) {
|
||||
val source = ImageDecoder.createSource(resources.assets,
|
||||
"gainmaps/cave.jpg")
|
||||
|
||||
val sourceInfo = findViewById<TextView>(R.id.source_info)!!
|
||||
|
||||
val gainmapImage = ImageDecoder.decodeBitmap(source) { decoder, info, source ->
|
||||
decoder.allocator = ImageDecoder.ALLOCATOR_SOFTWARE
|
||||
sourceInfo.text =
|
||||
"Original size ${info.size.width}x${info.size.height}; mime-type = ${info.mimeType}"
|
||||
|
||||
when (mode) {
|
||||
DecodeMode.Full -> {}
|
||||
DecodeMode.Subsampled4 -> {
|
||||
decoder.setTargetSampleSize(4)
|
||||
}
|
||||
DecodeMode.Scaled66 -> {
|
||||
val size = info.size
|
||||
decoder.setTargetSize((size.width * .66).toInt(), (size.height * .66).toInt())
|
||||
}
|
||||
DecodeMode.CropedSquared -> {
|
||||
val dimen = minOf(info.size.width, info.size.height)
|
||||
decoder.crop = Rect(50, 50, dimen - 100, dimen - 100)
|
||||
}
|
||||
DecodeMode.CropedSquaredScaled33 -> {
|
||||
val size = info.size
|
||||
val targetWidth = (size.width * .33).toInt()
|
||||
val targetHeight = (size.height * .33).toInt()
|
||||
decoder.setTargetSize(targetWidth, targetHeight)
|
||||
val dimen = minOf(targetWidth, targetHeight)
|
||||
decoder.crop = Rect(50, 50, dimen - 100, dimen - 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val gainmapContents = gainmapImage.gainmap!!.gainmapContents!!
|
||||
val sdrBitmap = gainmapImage.also { it.gainmap = null }
|
||||
|
||||
findViewById<ImageView>(R.id.sdr_source)!!.setImageBitmap(sdrBitmap)
|
||||
findViewById<TextView>(R.id.sdr_label)!!.text =
|
||||
"SDR Size: ${sdrBitmap.width}x${sdrBitmap.height}"
|
||||
|
||||
findViewById<ImageView>(R.id.gainmap)!!.setImageBitmap(gainmapContents)
|
||||
findViewById<TextView>(R.id.gainmap_label)!!.text =
|
||||
"Gainmap Size: ${gainmapContents.width}x${gainmapContents.height}"
|
||||
}
|
||||
|
||||
override fun onFinishInflate() {
|
||||
super.onFinishInflate()
|
||||
decode(DecodeMode.Full)
|
||||
|
||||
findViewById<Button>(R.id.decode_full)!!.setOnClickListener {
|
||||
decode(DecodeMode.Full)
|
||||
}
|
||||
findViewById<Button>(R.id.decode_subsampled4)!!.setOnClickListener {
|
||||
decode(DecodeMode.Subsampled4)
|
||||
}
|
||||
findViewById<Button>(R.id.decode_scaled66)!!.setOnClickListener {
|
||||
decode(DecodeMode.Scaled66)
|
||||
}
|
||||
findViewById<Button>(R.id.decode_crop)!!.setOnClickListener {
|
||||
decode(DecodeMode.CropedSquared)
|
||||
}
|
||||
findViewById<Button>(R.id.decode_cropScaled33)!!.setOnClickListener {
|
||||
decode(DecodeMode.CropedSquaredScaled33)
|
||||
}
|
||||
}
|
||||
}
|
||||
183
tests/SilkFX/src/com/android/test/silkfx/hdr/GainmapImage.kt
Normal file
183
tests/SilkFX/src/com/android/test/silkfx/hdr/GainmapImage.kt
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.test.silkfx.hdr
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.ColorMatrixColorFilter
|
||||
import android.graphics.Gainmap
|
||||
import android.graphics.ImageDecoder
|
||||
import android.graphics.Paint
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.RadioGroup
|
||||
import android.widget.Spinner
|
||||
import android.widget.TextView
|
||||
import com.android.test.silkfx.R
|
||||
import com.davemorrissey.labs.subscaleview.ImageSource
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||
|
||||
class GainmapImage(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) {
|
||||
|
||||
private val gainmapImages: Array<String>
|
||||
private var selectedImage = -1
|
||||
private var outputMode = R.id.output_hdr
|
||||
private var bitmap: Bitmap? = null
|
||||
private var gainmap: Gainmap? = null
|
||||
private var gainmapVisualizer: Bitmap? = null
|
||||
private lateinit var imageView: SubsamplingScaleImageView
|
||||
|
||||
init {
|
||||
gainmapImages = context.assets.list("gainmaps")!!
|
||||
}
|
||||
|
||||
fun setImageSource(source: ImageDecoder.Source) {
|
||||
findViewById<Spinner>(R.id.image_selection)!!.visibility = View.GONE
|
||||
doDecode(source)
|
||||
}
|
||||
|
||||
override fun onFinishInflate() {
|
||||
super.onFinishInflate()
|
||||
|
||||
imageView = findViewById(R.id.image)!!
|
||||
|
||||
findViewById<RadioGroup>(R.id.output_mode)!!.also {
|
||||
it.check(outputMode)
|
||||
it.setOnCheckedChangeListener { _, checkedId ->
|
||||
val previousMode = outputMode
|
||||
outputMode = checkedId
|
||||
if (previousMode == R.id.output_sdr && checkedId == R.id.output_hdr) {
|
||||
animateToHdr()
|
||||
} else if (previousMode == R.id.output_hdr && checkedId == R.id.output_sdr) {
|
||||
animateToSdr()
|
||||
} else {
|
||||
updateDisplay()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val spinner = findViewById<Spinner>(R.id.image_selection)!!
|
||||
val adapter = ArrayAdapter(context, android.R.layout.simple_spinner_item, gainmapImages)
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
spinner.adapter = adapter
|
||||
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(
|
||||
parent: AdapterView<*>?,
|
||||
view: View?,
|
||||
position: Int,
|
||||
id: Long
|
||||
) {
|
||||
setImage(position)
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||
}
|
||||
}
|
||||
|
||||
setImage(gainmapImages.indexOf("cave.jpg"))
|
||||
|
||||
imageView.apply {
|
||||
isClickable = true
|
||||
setOnClickListener {
|
||||
animate().alpha(.5f).withEndAction {
|
||||
animate().alpha(1f).start()
|
||||
}.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setImage(position: Int) {
|
||||
if (selectedImage == position) return
|
||||
selectedImage = position
|
||||
val source = ImageDecoder.createSource(resources.assets,
|
||||
"gainmaps/${gainmapImages[position]}")
|
||||
doDecode(source)
|
||||
}
|
||||
|
||||
private fun doDecode(source: ImageDecoder.Source) {
|
||||
gainmap = null
|
||||
bitmap = ImageDecoder.decodeBitmap(source) { decoder, info, source ->
|
||||
decoder.allocator = ImageDecoder.ALLOCATOR_SOFTWARE
|
||||
}
|
||||
if (!bitmap!!.hasGainmap()) {
|
||||
outputMode = R.id.output_sdr
|
||||
findViewById<TextView>(R.id.error_msg)!!.also {
|
||||
it.visibility = View.VISIBLE
|
||||
it.text = "Image doesn't have a gainmap, only showing in SDR"
|
||||
}
|
||||
findViewById<RadioGroup>(R.id.output_mode)!!.also {
|
||||
it.check(R.id.output_sdr)
|
||||
it.visibility = View.GONE
|
||||
}
|
||||
} else {
|
||||
findViewById<TextView>(R.id.error_msg)!!.visibility = View.GONE
|
||||
findViewById<RadioGroup>(R.id.output_mode)!!.visibility = View.VISIBLE
|
||||
|
||||
gainmap = bitmap!!.gainmap
|
||||
val map = gainmap!!.gainmapContents
|
||||
if (map.config != Bitmap.Config.ALPHA_8) {
|
||||
gainmapVisualizer = map
|
||||
} else {
|
||||
gainmapVisualizer = Bitmap.createBitmap(map.width, map.height,
|
||||
Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(gainmapVisualizer!!)
|
||||
val paint = Paint()
|
||||
paint.colorFilter = ColorMatrixColorFilter(
|
||||
floatArrayOf(
|
||||
0f, 0f, 0f, 1f, 0f,
|
||||
0f, 0f, 0f, 1f, 0f,
|
||||
0f, 0f, 0f, 1f, 0f,
|
||||
0f, 0f, 0f, 0f, 255f
|
||||
)
|
||||
)
|
||||
canvas.drawBitmap(map, 0f, 0f, paint)
|
||||
canvas.setBitmap(null)
|
||||
}
|
||||
}
|
||||
|
||||
updateDisplay()
|
||||
}
|
||||
|
||||
private fun animateToHdr() {
|
||||
if (bitmap == null || gainmap == null) return
|
||||
|
||||
// TODO: Trigger an animation
|
||||
updateDisplay()
|
||||
}
|
||||
|
||||
private fun animateToSdr() {
|
||||
if (bitmap == null) return
|
||||
|
||||
// TODO: Trigger an animation
|
||||
updateDisplay()
|
||||
}
|
||||
|
||||
private fun updateDisplay() {
|
||||
if (bitmap == null) return
|
||||
|
||||
imageView.setImage(ImageSource.cachedBitmap(when (outputMode) {
|
||||
R.id.output_hdr -> { bitmap!!.gainmap = gainmap; bitmap!! }
|
||||
R.id.output_sdr -> { bitmap!!.gainmap = null; bitmap!! }
|
||||
R.id.output_gainmap -> gainmapVisualizer!!
|
||||
else -> throw IllegalStateException()
|
||||
}))
|
||||
}
|
||||
}
|
||||
@@ -26,9 +26,7 @@ import android.util.AttributeSet
|
||||
import com.android.test.silkfx.common.BaseDrawingView
|
||||
import kotlin.math.min
|
||||
|
||||
class RadialGlow : BaseDrawingView {
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
|
||||
class RadialGlow(context: Context, attrs: AttributeSet?) : BaseDrawingView(context, attrs) {
|
||||
|
||||
var glowToggle = false
|
||||
|
||||
|
||||
Reference in New Issue
Block a user