Skip to content

Commit

Permalink
Merge pull request #1424 from pedroSG94/feature/crop-filter
Browse files Browse the repository at this point in the history
add CropFilterRender
  • Loading branch information
pedroSG94 committed Mar 7, 2024
2 parents a0ca976 + 73dc88c commit 259165a
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 12 deletions.
9 changes: 8 additions & 1 deletion app/src/main/java/com/pedro/streamer/utils/FilterMenu.kt
Expand Up @@ -39,6 +39,7 @@ import com.pedro.encoder.input.gl.render.filters.ChromaFilterRender
import com.pedro.encoder.input.gl.render.filters.CircleFilterRender
import com.pedro.encoder.input.gl.render.filters.ColorFilterRender
import com.pedro.encoder.input.gl.render.filters.ContrastFilterRender
import com.pedro.encoder.input.gl.render.filters.CropFilterRender
import com.pedro.encoder.input.gl.render.filters.DuotoneFilterRender
import com.pedro.encoder.input.gl.render.filters.EarlyBirdFilterRender
import com.pedro.encoder.input.gl.render.filters.EdgeDetectionFilterRender
Expand All @@ -52,7 +53,6 @@ import com.pedro.encoder.input.gl.render.filters.Image70sFilterRender
import com.pedro.encoder.input.gl.render.filters.LamoishFilterRender
import com.pedro.encoder.input.gl.render.filters.MoneyFilterRender
import com.pedro.encoder.input.gl.render.filters.NegativeFilterRender
import com.pedro.encoder.input.gl.render.filters.NoFilterRender
import com.pedro.encoder.input.gl.render.filters.PixelatedFilterRender
import com.pedro.encoder.input.gl.render.filters.PolygonizationFilterRender
import com.pedro.encoder.input.gl.render.filters.RGBSaturationFilterRender
Expand Down Expand Up @@ -153,6 +153,13 @@ class FilterMenu(private val context: Context) {
glInterface.setFilter(ContrastFilterRender())
return true
}
R.id.crop -> {
glInterface.setFilter(CropFilterRender().apply {
//crop center of the image with 40% of width and 40% of height
setCropArea(30f, 30f, 40f, 40f)
})
return true
}
R.id.duotone -> {
glInterface.setFilter(DuotoneFilterRender())
return true
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/res/menu/rotation_menu.xml
Expand Up @@ -92,6 +92,10 @@
android:id="@+id/contrast"
android:title="@string/contrast"
/>
<item
android:id="@+id/crop"
android:title="@string/crop"
/>
<item
android:id="@+id/duotone"
android:title="@string/duotone"
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Expand Up @@ -25,6 +25,7 @@
<string name="circle">Circle</string>
<string name="color">Color</string>
<string name="contrast">Contrast</string>
<string name="crop">Crop</string>
<string name="duotone">Duotone</string>
<string name="earlybird">EarlyBird</string>
<string name="edge_detection">Edge detection</string>
Expand Down
Expand Up @@ -77,7 +77,7 @@ public ScreenRender() {
public void initGl(Context context) {
GlUtil.checkGlError("initGl start");
String vertexShader = GlUtil.getStringFromRaw(context, R.raw.simple_vertex);
String fragmentShader = GlUtil.getStringFromRaw(context, R.raw.screen_fragment);
String fragmentShader = GlUtil.getStringFromRaw(context, R.raw.simple_fragment);

program = GlUtil.createProgram(vertexShader, fragmentShader);
aPositionHandle = GLES20.glGetAttribLocation(program, "aPosition");
Expand Down
@@ -0,0 +1,125 @@
/*
* Copyright (C) 2023 pedroSG94.
*
* 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.pedro.encoder.input.gl.render.filters

import android.content.Context
import android.opengl.GLES20
import android.opengl.Matrix
import android.os.Build
import androidx.annotation.RequiresApi
import com.pedro.encoder.R
import com.pedro.encoder.input.gl.render.BaseRenderOffScreen
import com.pedro.encoder.utils.gl.GlUtil
import java.nio.ByteBuffer
import java.nio.ByteOrder

/**
* Created by pedro on 6/3/24.
*/
@RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
class CropFilterRender: BaseFilterRender() {

//rotation matrix
private val squareVertexDataFilter = floatArrayOf(
// X, Y, Z, U, V
-1f, -1f, 0f, 0f, 0f, //bottom left
1f, -1f, 0f, 1f, 0f, //bottom right
-1f, 1f, 0f, 0f, 1f, //top left
1f, 1f, 0f, 1f, 1f
)

private var program = -1
private var aPositionHandle = -1
private var aTextureHandle = -1
private var uMVPMatrixHandle = -1
private var uSTMatrixHandle = -1
private var uSamplerHandle = -1

private var positionMatrix = FloatArray(16)

init {
squareVertex =
ByteBuffer.allocateDirect(squareVertexDataFilter.size * BaseRenderOffScreen.FLOAT_SIZE_BYTES)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
squareVertex.put(squareVertexDataFilter).position(0)
Matrix.setIdentityM(MVPMatrix, 0)
Matrix.setIdentityM(STMatrix, 0)
Matrix.setIdentityM(positionMatrix, 0)
}

override fun initGlFilter(context: Context?) {
val vertexShader = GlUtil.getStringFromRaw(context, R.raw.simple_vertex)
val fragmentShader = GlUtil.getStringFromRaw(context, R.raw.simple_fragment)
program = GlUtil.createProgram(vertexShader, fragmentShader)
aPositionHandle = GLES20.glGetAttribLocation(program, "aPosition")
aTextureHandle = GLES20.glGetAttribLocation(program, "aTextureCoord")
uMVPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix")
uSTMatrixHandle = GLES20.glGetUniformLocation(program, "uSTMatrix")
uSamplerHandle = GLES20.glGetUniformLocation(program, "uSampler")
}

override fun drawFilter() {
GLES20.glUseProgram(program)
squareVertex.position(BaseRenderOffScreen.SQUARE_VERTEX_DATA_POS_OFFSET)
GLES20.glVertexAttribPointer(
aPositionHandle, 3, GLES20.GL_FLOAT, false,
BaseRenderOffScreen.SQUARE_VERTEX_DATA_STRIDE_BYTES, squareVertex
)
GLES20.glEnableVertexAttribArray(aPositionHandle)
squareVertex.position(BaseRenderOffScreen.SQUARE_VERTEX_DATA_UV_OFFSET)
GLES20.glVertexAttribPointer(
aTextureHandle, 2, GLES20.GL_FLOAT, false,
BaseRenderOffScreen.SQUARE_VERTEX_DATA_STRIDE_BYTES, squareVertex
)
GLES20.glEnableVertexAttribArray(aTextureHandle)
GLES20.glUniformMatrix4fv(uMVPMatrixHandle, 1, false, MVPMatrix, 0)
GLES20.glUniformMatrix4fv(uSTMatrixHandle, 1, false, STMatrix, 0)
GLES20.glUniform1i(uSamplerHandle, 4)
GLES20.glActiveTexture(GLES20.GL_TEXTURE4)
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, previousTexId)
}

override fun release() {
GLES20.glDeleteProgram(program)
}

/**
* Set crop area in percentage. Starting from top left corner.
* Moved in right bottom
*/
fun setCropArea(offsetX: Float, offsetY: Float, width: Float, height: Float) {
val scaleX = 1f / (width / 100f)
val scaleY = 1f / (height / 100f)

val initialX = 1f - (1f / scaleX)
val initialY = -(1f - (1f / scaleY))
val percentX = initialX / (50f - (width / 2f))
val percentY = -initialY / (50f - (height / 2f))

val oX = initialX - (offsetX * percentX)
val oY = initialY + (offsetY * percentY)

//reset matrix
Matrix.setIdentityM(positionMatrix, 0)
Matrix.setIdentityM(MVPMatrix, 0)

Matrix.scaleM(positionMatrix, 0, scaleX, scaleY, 0f)
Matrix.translateM(positionMatrix, 0, oX, oY, 0f)
Matrix.multiplyMM(MVPMatrix, 0, positionMatrix, 0, MVPMatrix, 0)
}
}
8 changes: 0 additions & 8 deletions encoder/src/main/res/raw/screen_fragment.glsl

This file was deleted.

3 changes: 1 addition & 2 deletions encoder/src/main/res/raw/simple_fragment.glsl
@@ -1,7 +1,6 @@
precision mediump float;
precision highp float;

uniform sampler2D uSampler;

varying vec2 vTextureCoord;

void main() {
Expand Down

0 comments on commit 259165a

Please sign in to comment.