Nikolay Igotti
4 years ago
5 changed files with 168 additions and 168 deletions
@ -1,162 +1,162 @@
|
||||
/* |
||||
* Copyright 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. |
||||
*/ |
||||
package example.imageviewer.utils |
||||
|
||||
import androidx.compose.desktop.AppManager |
||||
import androidx.compose.ui.unit.IntSize |
||||
import java.awt.Dimension |
||||
import java.awt.Graphics2D |
||||
import java.awt.Rectangle |
||||
import java.awt.Toolkit |
||||
import java.awt.image.BufferedImage |
||||
import java.io.ByteArrayOutputStream |
||||
import java.io.File |
||||
import java.io.IOException |
||||
import javax.imageio.ImageIO |
||||
import java.awt.image.BufferedImageOp |
||||
import java.awt.image.ConvolveOp |
||||
import java.awt.image.Kernel |
||||
|
||||
fun scaleBitmapAspectRatio( |
||||
bitmap: BufferedImage, |
||||
width: Int, |
||||
height: Int |
||||
): BufferedImage { |
||||
val boundW: Float = width.toFloat() |
||||
val boundH: Float = height.toFloat() |
||||
|
||||
val ratioX: Float = boundW / bitmap.width |
||||
val ratioY: Float = boundH / bitmap.height |
||||
val ratio: Float = if (ratioX < ratioY) ratioX else ratioY |
||||
|
||||
val resultH = (bitmap.height * ratio).toInt() |
||||
val resultW = (bitmap.width * ratio).toInt() |
||||
|
||||
val result = BufferedImage(resultW, resultH, BufferedImage.TYPE_INT_ARGB) |
||||
val graphics = result.createGraphics() |
||||
graphics.drawImage(bitmap, 0, 0, resultW, resultH, null) |
||||
graphics.dispose() |
||||
|
||||
return result |
||||
} |
||||
|
||||
fun getDisplayBounds(bitmap: BufferedImage): Rectangle { |
||||
|
||||
val boundW: Float = displayWidth().toFloat() |
||||
val boundH: Float = displayHeight().toFloat() |
||||
|
||||
val ratioX: Float = bitmap.width / boundW |
||||
val ratioY: Float = bitmap.height / boundH |
||||
|
||||
val ratio: Float = if (ratioX > ratioY) ratioX else ratioY |
||||
|
||||
val resultW = (boundW * ratio) |
||||
val resultH = (boundH * ratio) |
||||
|
||||
return Rectangle(0, 0, resultW.toInt(), resultH.toInt()) |
||||
} |
||||
|
||||
fun applyGrayScaleFilter(bitmap: BufferedImage): BufferedImage { |
||||
|
||||
val result = BufferedImage( |
||||
bitmap.getWidth(), |
||||
bitmap.getHeight(), |
||||
BufferedImage.TYPE_BYTE_GRAY) |
||||
|
||||
val graphics = result.getGraphics() |
||||
graphics.drawImage(bitmap, 0, 0, null) |
||||
graphics.dispose() |
||||
|
||||
return result |
||||
} |
||||
|
||||
fun applyPixelFilter(bitmap: BufferedImage): BufferedImage { |
||||
|
||||
val w: Int = bitmap.width |
||||
val h: Int = bitmap.height |
||||
|
||||
var result = scaleBitmapAspectRatio(bitmap, w / 20, h / 20) |
||||
result = scaleBitmapAspectRatio(result, w, h) |
||||
|
||||
return result |
||||
} |
||||
|
||||
fun applyBlurFilter(bitmap: BufferedImage): BufferedImage { |
||||
|
||||
var result = BufferedImage(bitmap.getWidth(), bitmap.getHeight(), bitmap.type) |
||||
|
||||
val graphics = result.getGraphics() |
||||
graphics.drawImage(bitmap, 0, 0, null) |
||||
graphics.dispose() |
||||
|
||||
val radius = 11 |
||||
val size = 11 |
||||
val weight: Float = 1.0f / (size * size) |
||||
val matrix = FloatArray(size * size) |
||||
|
||||
for (i in 0..matrix.size - 1) { |
||||
matrix[i] = weight |
||||
} |
||||
|
||||
val kernel = Kernel(radius, size, matrix) |
||||
val op = ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null) |
||||
result = op.filter(result, null) |
||||
|
||||
return result.getSubimage( |
||||
radius, |
||||
radius, |
||||
result.width - radius * 2, |
||||
result.height - radius * 2 |
||||
) |
||||
} |
||||
|
||||
fun displayWidth(): Int { |
||||
val window = AppManager.getCurrentFocusedWindow() |
||||
if (window != null) { |
||||
return window.width |
||||
} |
||||
return 0 |
||||
} |
||||
|
||||
fun displayHeight(): Int { |
||||
val window = AppManager.getCurrentFocusedWindow() |
||||
if (window != null) { |
||||
return window.height |
||||
} |
||||
return 0 |
||||
} |
||||
|
||||
fun toByteArray(bitmap: BufferedImage) : ByteArray { |
||||
val baos = ByteArrayOutputStream() |
||||
ImageIO.write(bitmap, "png", baos) |
||||
return baos.toByteArray() |
||||
} |
||||
|
||||
fun cropImage(bitmap: BufferedImage, crop: Rectangle) : BufferedImage { |
||||
val result = BufferedImage(crop.width, crop.height, bitmap.type) |
||||
val graphics = result.createGraphics() |
||||
graphics.drawImage(bitmap, crop.x, crop.y, crop.width, crop.height, null) |
||||
return result |
||||
} |
||||
|
||||
fun getPreferredWindowSize(desiredWidth: Int, desiredHeight: Int): IntSize { |
||||
val screenSize: Dimension = Toolkit.getDefaultToolkit().screenSize |
||||
val preferredWidth: Int = (screenSize.width * 0.8f).toInt() |
||||
val preferredHeight: Int = (screenSize.height * 0.8f).toInt() |
||||
val width: Int = if (desiredWidth < preferredWidth) desiredWidth else preferredWidth |
||||
val height: Int = if (desiredHeight < preferredHeight) desiredHeight else preferredHeight |
||||
return IntSize(width, height) |
||||
} |
||||
/* |
||||
* Copyright 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. |
||||
*/ |
||||
package example.imageviewer.utils |
||||
|
||||
import androidx.compose.desktop.AppManager |
||||
import androidx.compose.ui.unit.IntSize |
||||
import java.awt.Dimension |
||||
import java.awt.Graphics2D |
||||
import java.awt.Rectangle |
||||
import java.awt.Toolkit |
||||
import java.awt.image.BufferedImage |
||||
import java.io.ByteArrayOutputStream |
||||
import java.io.File |
||||
import java.io.IOException |
||||
import javax.imageio.ImageIO |
||||
import java.awt.image.BufferedImageOp |
||||
import java.awt.image.ConvolveOp |
||||
import java.awt.image.Kernel |
||||
|
||||
fun scaleBitmapAspectRatio( |
||||
bitmap: BufferedImage, |
||||
width: Int, |
||||
height: Int |
||||
): BufferedImage { |
||||
val boundW: Float = width.toFloat() |
||||
val boundH: Float = height.toFloat() |
||||
|
||||
val ratioX: Float = boundW / bitmap.width |
||||
val ratioY: Float = boundH / bitmap.height |
||||
val ratio: Float = if (ratioX < ratioY) ratioX else ratioY |
||||
|
||||
val resultH = (bitmap.height * ratio).toInt() |
||||
val resultW = (bitmap.width * ratio).toInt() |
||||
|
||||
val result = BufferedImage(resultW, resultH, BufferedImage.TYPE_INT_ARGB) |
||||
val graphics = result.createGraphics() |
||||
graphics.drawImage(bitmap, 0, 0, resultW, resultH, null) |
||||
graphics.dispose() |
||||
|
||||
return result |
||||
} |
||||
|
||||
fun getDisplayBounds(bitmap: BufferedImage): Rectangle { |
||||
|
||||
val boundW: Float = displayWidth().toFloat() |
||||
val boundH: Float = displayHeight().toFloat() |
||||
|
||||
val ratioX: Float = bitmap.width / boundW |
||||
val ratioY: Float = bitmap.height / boundH |
||||
|
||||
val ratio: Float = if (ratioX > ratioY) ratioX else ratioY |
||||
|
||||
val resultW = (boundW * ratio) |
||||
val resultH = (boundH * ratio) |
||||
|
||||
return Rectangle(0, 0, resultW.toInt(), resultH.toInt()) |
||||
} |
||||
|
||||
fun applyGrayScaleFilter(bitmap: BufferedImage): BufferedImage { |
||||
|
||||
val result = BufferedImage( |
||||
bitmap.getWidth(), |
||||
bitmap.getHeight(), |
||||
BufferedImage.TYPE_BYTE_GRAY) |
||||
|
||||
val graphics = result.getGraphics() |
||||
graphics.drawImage(bitmap, 0, 0, null) |
||||
graphics.dispose() |
||||
|
||||
return result |
||||
} |
||||
|
||||
fun applyPixelFilter(bitmap: BufferedImage): BufferedImage { |
||||
|
||||
val w: Int = bitmap.width |
||||
val h: Int = bitmap.height |
||||
|
||||
var result = scaleBitmapAspectRatio(bitmap, w / 20, h / 20) |
||||
result = scaleBitmapAspectRatio(result, w, h) |
||||
|
||||
return result |
||||
} |
||||
|
||||
fun applyBlurFilter(bitmap: BufferedImage): BufferedImage { |
||||
|
||||
var result = BufferedImage(bitmap.getWidth(), bitmap.getHeight(), bitmap.type) |
||||
|
||||
val graphics = result.getGraphics() |
||||
graphics.drawImage(bitmap, 0, 0, null) |
||||
graphics.dispose() |
||||
|
||||
val radius = 11 |
||||
val size = 11 |
||||
val weight: Float = 1.0f / (size * size) |
||||
val matrix = FloatArray(size * size) |
||||
|
||||
for (i in 0..matrix.size - 1) { |
||||
matrix[i] = weight |
||||
} |
||||
|
||||
val kernel = Kernel(radius, size, matrix) |
||||
val op = ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null) |
||||
result = op.filter(result, null) |
||||
|
||||
return result.getSubimage( |
||||
radius, |
||||
radius, |
||||
result.width - radius * 2, |
||||
result.height - radius * 2 |
||||
) |
||||
} |
||||
|
||||
fun displayWidth(): Int { |
||||
val window = AppManager.focusedWindow |
||||
if (window != null) { |
||||
return window.width |
||||
} |
||||
return 0 |
||||
} |
||||
|
||||
fun displayHeight(): Int { |
||||
val window = AppManager.focusedWindow |
||||
if (window != null) { |
||||
return window.height |
||||
} |
||||
return 0 |
||||
} |
||||
|
||||
fun toByteArray(bitmap: BufferedImage) : ByteArray { |
||||
val baos = ByteArrayOutputStream() |
||||
ImageIO.write(bitmap, "png", baos) |
||||
return baos.toByteArray() |
||||
} |
||||
|
||||
fun cropImage(bitmap: BufferedImage, crop: Rectangle) : BufferedImage { |
||||
val result = BufferedImage(crop.width, crop.height, bitmap.type) |
||||
val graphics = result.createGraphics() |
||||
graphics.drawImage(bitmap, crop.x, crop.y, crop.width, crop.height, null) |
||||
return result |
||||
} |
||||
|
||||
fun getPreferredWindowSize(desiredWidth: Int, desiredHeight: Int): IntSize { |
||||
val screenSize: Dimension = Toolkit.getDefaultToolkit().screenSize |
||||
val preferredWidth: Int = (screenSize.width * 0.8f).toInt() |
||||
val preferredHeight: Int = (screenSize.height * 0.8f).toInt() |
||||
val width: Int = if (desiredWidth < preferredWidth) desiredWidth else preferredWidth |
||||
val height: Int = if (desiredHeight < preferredHeight) desiredHeight else preferredHeight |
||||
return IntSize(width, height) |
||||
} |
||||
|
Loading…
Reference in new issue