Add sepia, grayscale, and inverted filters to the demo app.

PiperOrigin-RevId: 471782565
This commit is contained in:
leonwind 2022-09-02 13:10:29 +00:00 committed by Marc Baechinger
parent 1a4cd549a4
commit 87926f0ba8
3 changed files with 69 additions and 9 deletions

View File

@ -67,7 +67,11 @@ public final class ConfigurationActivity extends AppCompatActivity {
public static final String PERIODIC_VIGNETTE_CENTER_Y = "periodic_vignette_center_y"; public static final String PERIODIC_VIGNETTE_CENTER_Y = "periodic_vignette_center_y";
public static final String PERIODIC_VIGNETTE_INNER_RADIUS = "periodic_vignette_inner_radius"; public static final String PERIODIC_VIGNETTE_INNER_RADIUS = "periodic_vignette_inner_radius";
public static final String PERIODIC_VIGNETTE_OUTER_RADIUS = "periodic_vignette_outer_radius"; public static final String PERIODIC_VIGNETTE_OUTER_RADIUS = "periodic_vignette_outer_radius";
public static final String COLOR_FILTER_SELECTION = "color_filter_selection";
public static final String CONTRAST_VALUE = "contrast_value"; public static final String CONTRAST_VALUE = "contrast_value";
public static final int COLOR_FILTER_GRAYSCALE = 0;
public static final int COLOR_FILTER_INVERTED = 1;
public static final int COLOR_FILTER_SEPIA = 2;
private static final String[] INPUT_URIS = { private static final String[] INPUT_URIS = {
"https://storage.googleapis.com/exoplayer-test-media-1/mp4/android-screens-10s.mp4", "https://storage.googleapis.com/exoplayer-test-media-1/mp4/android-screens-10s.mp4",
"https://storage.googleapis.com/exoplayer-test-media-0/android-block-1080-hevc.mp4", "https://storage.googleapis.com/exoplayer-test-media-0/android-block-1080-hevc.mp4",
@ -101,14 +105,16 @@ public final class ConfigurationActivity extends AppCompatActivity {
private static final String[] DEMO_EFFECTS = { private static final String[] DEMO_EFFECTS = {
"Dizzy crop", "Dizzy crop",
"Edge detector (Media Pipe)", "Edge detector (Media Pipe)",
"Color filters",
"Contrast", "Contrast",
"Periodic vignette", "Periodic vignette",
"3D spin", "3D spin",
"Overlay logo & timer", "Overlay logo & timer",
"Zoom in start", "Zoom in start",
}; };
private static final int CONTRAST_INDEX = 2; private static final int COLOR_FILTERS_INDEX = 2;
private static final int PERIODIC_VIGNETTE_INDEX = 3; private static final int CONTRAST_INDEX = 3;
private static final int PERIODIC_VIGNETTE_INDEX = 4;
private static final String SAME_AS_INPUT_OPTION = "same as input"; private static final String SAME_AS_INPUT_OPTION = "same as input";
private static final float HALF_DIAGONAL = 1f / (float) Math.sqrt(2); private static final float HALF_DIAGONAL = 1f / (float) Math.sqrt(2);
@ -132,6 +138,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
private int inputUriPosition; private int inputUriPosition;
private long trimStartMs; private long trimStartMs;
private long trimEndMs; private long trimEndMs;
private int colorFilterSelection;
private float contrastValue; private float contrastValue;
private float periodicVignetteCenterX; private float periodicVignetteCenterX;
private float periodicVignetteCenterY; private float periodicVignetteCenterY;
@ -288,6 +295,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
ENABLE_REQUEST_SDR_TONE_MAPPING, enableRequestSdrToneMappingCheckBox.isChecked()); ENABLE_REQUEST_SDR_TONE_MAPPING, enableRequestSdrToneMappingCheckBox.isChecked());
bundle.putBoolean(ENABLE_HDR_EDITING, enableHdrEditingCheckBox.isChecked()); bundle.putBoolean(ENABLE_HDR_EDITING, enableHdrEditingCheckBox.isChecked());
bundle.putBooleanArray(DEMO_EFFECTS_SELECTIONS, demoEffectsSelections); bundle.putBooleanArray(DEMO_EFFECTS_SELECTIONS, demoEffectsSelections);
bundle.putInt(COLOR_FILTER_SELECTION, colorFilterSelection);
bundle.putFloat(CONTRAST_VALUE, contrastValue); bundle.putFloat(CONTRAST_VALUE, contrastValue);
bundle.putFloat(PERIODIC_VIGNETTE_CENTER_X, periodicVignetteCenterX); bundle.putFloat(PERIODIC_VIGNETTE_CENTER_X, periodicVignetteCenterX);
bundle.putFloat(PERIODIC_VIGNETTE_CENTER_Y, periodicVignetteCenterY); bundle.putFloat(PERIODIC_VIGNETTE_CENTER_Y, periodicVignetteCenterY);
@ -356,6 +364,9 @@ public final class ConfigurationActivity extends AppCompatActivity {
} }
switch (which) { switch (which) {
case COLOR_FILTERS_INDEX:
controlColorFiltersSettings();
break;
case CONTRAST_INDEX: case CONTRAST_INDEX:
controlContrastSettings(); controlContrastSettings();
break; break;
@ -365,6 +376,24 @@ public final class ConfigurationActivity extends AppCompatActivity {
} }
} }
private void controlColorFiltersSettings() {
new AlertDialog.Builder(/* context= */ this)
.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> dialogInterface.dismiss())
.setSingleChoiceItems(
this.getResources().getStringArray(R.array.color_filter_options),
colorFilterSelection,
(DialogInterface dialogInterface, int i) -> {
checkState(
i == COLOR_FILTER_GRAYSCALE
|| i == COLOR_FILTER_INVERTED
|| i == COLOR_FILTER_SEPIA);
colorFilterSelection = i;
dialogInterface.dismiss();
})
.create()
.show();
}
private void controlContrastSettings() { private void controlContrastSettings() {
View dialogView = getLayoutInflater().inflate(R.layout.contrast_options, /* root= */ null); View dialogView = getLayoutInflater().inflate(R.layout.contrast_options, /* root= */ null);
Slider contrastSlider = checkNotNull(dialogView.findViewById(R.id.contrast_slider)); Slider contrastSlider = checkNotNull(dialogView.findViewById(R.id.contrast_slider));
@ -372,9 +401,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
.setView(dialogView) .setView(dialogView)
.setPositiveButton( .setPositiveButton(
android.R.string.ok, android.R.string.ok,
(DialogInterface dialogInterface, int i) -> { (DialogInterface dialogInterface, int i) -> contrastValue = contrastSlider.getValue())
contrastValue = contrastSlider.getValue();
})
.create() .create()
.show(); .show();
} }

View File

@ -40,6 +40,8 @@ import androidx.media3.common.Effect;
import androidx.media3.effect.Contrast; import androidx.media3.effect.Contrast;
import androidx.media3.effect.GlEffect; import androidx.media3.effect.GlEffect;
import androidx.media3.effect.GlTextureProcessor; import androidx.media3.effect.GlTextureProcessor;
import androidx.media3.effect.RgbFilter;
import androidx.media3.effect.RgbMatrix;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.MediaItem;
@ -308,9 +310,35 @@ public final class TransformerActivity extends AppCompatActivity {
} }
} }
if (selectedEffects[2]) { if (selectedEffects[2]) {
effects.add(new Contrast(bundle.getFloat(ConfigurationActivity.CONTRAST_VALUE))); switch (bundle.getInt(ConfigurationActivity.COLOR_FILTER_SELECTION)) {
case ConfigurationActivity.COLOR_FILTER_GRAYSCALE:
effects.add(RgbFilter.createGrayscaleFilter());
break;
case ConfigurationActivity.COLOR_FILTER_INVERTED:
effects.add(RgbFilter.createInvertedFilter());
break;
case ConfigurationActivity.COLOR_FILTER_SEPIA:
// W3C Sepia RGBA matrix with sRGB as a target color space:
// https://www.w3.org/TR/filter-effects-1/#sepiaEquivalent
// The matrix is defined for the sRGB color space and the Transformer library
// uses a linear RGB color space internally. Meaning this is only for demonstration
// purposes and it does not display a correct sepia frame.
float[] sepiaMatrix = {
0.393f, 0.349f, 0.272f, 0, 0.769f, 0.686f, 0.534f, 0, 0.189f, 0.168f, 0.131f, 0, 0,
0, 0, 1
};
effects.add((RgbMatrix) (presentationTimeUs, useHdr) -> sepiaMatrix);
break;
default:
throw new IllegalStateException(
"Unexpected color filter "
+ bundle.getInt(ConfigurationActivity.COLOR_FILTER_SELECTION));
}
} }
if (selectedEffects[3]) { if (selectedEffects[3]) {
effects.add(new Contrast(bundle.getFloat(ConfigurationActivity.CONTRAST_VALUE)));
}
if (selectedEffects[4]) {
effects.add( effects.add(
(GlEffect) (GlEffect)
(Context context, boolean useHdr) -> (Context context, boolean useHdr) ->
@ -325,13 +353,13 @@ public final class TransformerActivity extends AppCompatActivity {
ConfigurationActivity.PERIODIC_VIGNETTE_OUTER_RADIUS), ConfigurationActivity.PERIODIC_VIGNETTE_OUTER_RADIUS),
bundle.getFloat(ConfigurationActivity.PERIODIC_VIGNETTE_OUTER_RADIUS))); bundle.getFloat(ConfigurationActivity.PERIODIC_VIGNETTE_OUTER_RADIUS)));
} }
if (selectedEffects[4]) { if (selectedEffects[5]) {
effects.add(MatrixTransformationFactory.createSpin3dEffect()); effects.add(MatrixTransformationFactory.createSpin3dEffect());
} }
if (selectedEffects[5]) { if (selectedEffects[6]) {
effects.add((GlEffect) BitmapOverlayProcessor::new); effects.add((GlEffect) BitmapOverlayProcessor::new);
} }
if (selectedEffects[6]) { if (selectedEffects[7]) {
effects.add(MatrixTransformationFactory.createZoomInTransition()); effects.add(MatrixTransformationFactory.createZoomInTransition());
} }
transformerBuilder.setVideoEffects(effects.build()); transformerBuilder.setVideoEffects(effects.build());

View File

@ -42,6 +42,11 @@
<string name="transformation_completed" translatable="false">Transformation completed in %d seconds.</string> <string name="transformation_completed" translatable="false">Transformation completed in %d seconds.</string>
<string name="transformation_error" translatable="false">Transformation error</string> <string name="transformation_error" translatable="false">Transformation error</string>
<string name="trim_range">Bounds in seconds</string> <string name="trim_range">Bounds in seconds</string>
<string-array name="color_filter_options">
<item>Grayscale</item>
<item>Inverted</item>
<item>Sepia</item>
</string-array>
<string name="contrast_value" translatable="false">Contrast value</string> <string name="contrast_value" translatable="false">Contrast value</string>
<string name="center_x">Center X</string> <string name="center_x">Center X</string>
<string name="center_y">Center Y</string> <string name="center_y">Center Y</string>