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 |
* Copyright 2020 The Android Open Source Project |
||||||
* |
* |
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
* you may not use this file except in compliance with the License. |
* you may not use this file except in compliance with the License. |
||||||
* You may obtain a copy of the License at |
* You may obtain a copy of the License at |
||||||
* |
* |
||||||
* http://www.apache.org/licenses/LICENSE-2.0 |
* http://www.apache.org/licenses/LICENSE-2.0 |
||||||
* |
* |
||||||
* Unless required by applicable law or agreed to in writing, software |
* Unless required by applicable law or agreed to in writing, software |
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
* See the License for the specific language governing permissions and |
* See the License for the specific language governing permissions and |
||||||
* limitations under the License. |
* limitations under the License. |
||||||
*/ |
*/ |
||||||
package example.imageviewer.utils |
package example.imageviewer.utils |
||||||
|
|
||||||
import androidx.compose.desktop.AppManager |
import androidx.compose.desktop.AppManager |
||||||
import androidx.compose.ui.unit.IntSize |
import androidx.compose.ui.unit.IntSize |
||||||
import java.awt.Dimension |
import java.awt.Dimension |
||||||
import java.awt.Graphics2D |
import java.awt.Graphics2D |
||||||
import java.awt.Rectangle |
import java.awt.Rectangle |
||||||
import java.awt.Toolkit |
import java.awt.Toolkit |
||||||
import java.awt.image.BufferedImage |
import java.awt.image.BufferedImage |
||||||
import java.io.ByteArrayOutputStream |
import java.io.ByteArrayOutputStream |
||||||
import java.io.File |
import java.io.File |
||||||
import java.io.IOException |
import java.io.IOException |
||||||
import javax.imageio.ImageIO |
import javax.imageio.ImageIO |
||||||
import java.awt.image.BufferedImageOp |
import java.awt.image.BufferedImageOp |
||||||
import java.awt.image.ConvolveOp |
import java.awt.image.ConvolveOp |
||||||
import java.awt.image.Kernel |
import java.awt.image.Kernel |
||||||
|
|
||||||
fun scaleBitmapAspectRatio( |
fun scaleBitmapAspectRatio( |
||||||
bitmap: BufferedImage, |
bitmap: BufferedImage, |
||||||
width: Int, |
width: Int, |
||||||
height: Int |
height: Int |
||||||
): BufferedImage { |
): BufferedImage { |
||||||
val boundW: Float = width.toFloat() |
val boundW: Float = width.toFloat() |
||||||
val boundH: Float = height.toFloat() |
val boundH: Float = height.toFloat() |
||||||
|
|
||||||
val ratioX: Float = boundW / bitmap.width |
val ratioX: Float = boundW / bitmap.width |
||||||
val ratioY: Float = boundH / bitmap.height |
val ratioY: Float = boundH / bitmap.height |
||||||
val ratio: Float = if (ratioX < ratioY) ratioX else ratioY |
val ratio: Float = if (ratioX < ratioY) ratioX else ratioY |
||||||
|
|
||||||
val resultH = (bitmap.height * ratio).toInt() |
val resultH = (bitmap.height * ratio).toInt() |
||||||
val resultW = (bitmap.width * ratio).toInt() |
val resultW = (bitmap.width * ratio).toInt() |
||||||
|
|
||||||
val result = BufferedImage(resultW, resultH, BufferedImage.TYPE_INT_ARGB) |
val result = BufferedImage(resultW, resultH, BufferedImage.TYPE_INT_ARGB) |
||||||
val graphics = result.createGraphics() |
val graphics = result.createGraphics() |
||||||
graphics.drawImage(bitmap, 0, 0, resultW, resultH, null) |
graphics.drawImage(bitmap, 0, 0, resultW, resultH, null) |
||||||
graphics.dispose() |
graphics.dispose() |
||||||
|
|
||||||
return result |
return result |
||||||
} |
} |
||||||
|
|
||||||
fun getDisplayBounds(bitmap: BufferedImage): Rectangle { |
fun getDisplayBounds(bitmap: BufferedImage): Rectangle { |
||||||
|
|
||||||
val boundW: Float = displayWidth().toFloat() |
val boundW: Float = displayWidth().toFloat() |
||||||
val boundH: Float = displayHeight().toFloat() |
val boundH: Float = displayHeight().toFloat() |
||||||
|
|
||||||
val ratioX: Float = bitmap.width / boundW |
val ratioX: Float = bitmap.width / boundW |
||||||
val ratioY: Float = bitmap.height / boundH |
val ratioY: Float = bitmap.height / boundH |
||||||
|
|
||||||
val ratio: Float = if (ratioX > ratioY) ratioX else ratioY |
val ratio: Float = if (ratioX > ratioY) ratioX else ratioY |
||||||
|
|
||||||
val resultW = (boundW * ratio) |
val resultW = (boundW * ratio) |
||||||
val resultH = (boundH * ratio) |
val resultH = (boundH * ratio) |
||||||
|
|
||||||
return Rectangle(0, 0, resultW.toInt(), resultH.toInt()) |
return Rectangle(0, 0, resultW.toInt(), resultH.toInt()) |
||||||
} |
} |
||||||
|
|
||||||
fun applyGrayScaleFilter(bitmap: BufferedImage): BufferedImage { |
fun applyGrayScaleFilter(bitmap: BufferedImage): BufferedImage { |
||||||
|
|
||||||
val result = BufferedImage( |
val result = BufferedImage( |
||||||
bitmap.getWidth(), |
bitmap.getWidth(), |
||||||
bitmap.getHeight(), |
bitmap.getHeight(), |
||||||
BufferedImage.TYPE_BYTE_GRAY) |
BufferedImage.TYPE_BYTE_GRAY) |
||||||
|
|
||||||
val graphics = result.getGraphics() |
val graphics = result.getGraphics() |
||||||
graphics.drawImage(bitmap, 0, 0, null) |
graphics.drawImage(bitmap, 0, 0, null) |
||||||
graphics.dispose() |
graphics.dispose() |
||||||
|
|
||||||
return result |
return result |
||||||
} |
} |
||||||
|
|
||||||
fun applyPixelFilter(bitmap: BufferedImage): BufferedImage { |
fun applyPixelFilter(bitmap: BufferedImage): BufferedImage { |
||||||
|
|
||||||
val w: Int = bitmap.width |
val w: Int = bitmap.width |
||||||
val h: Int = bitmap.height |
val h: Int = bitmap.height |
||||||
|
|
||||||
var result = scaleBitmapAspectRatio(bitmap, w / 20, h / 20) |
var result = scaleBitmapAspectRatio(bitmap, w / 20, h / 20) |
||||||
result = scaleBitmapAspectRatio(result, w, h) |
result = scaleBitmapAspectRatio(result, w, h) |
||||||
|
|
||||||
return result |
return result |
||||||
} |
} |
||||||
|
|
||||||
fun applyBlurFilter(bitmap: BufferedImage): BufferedImage { |
fun applyBlurFilter(bitmap: BufferedImage): BufferedImage { |
||||||
|
|
||||||
var result = BufferedImage(bitmap.getWidth(), bitmap.getHeight(), bitmap.type) |
var result = BufferedImage(bitmap.getWidth(), bitmap.getHeight(), bitmap.type) |
||||||
|
|
||||||
val graphics = result.getGraphics() |
val graphics = result.getGraphics() |
||||||
graphics.drawImage(bitmap, 0, 0, null) |
graphics.drawImage(bitmap, 0, 0, null) |
||||||
graphics.dispose() |
graphics.dispose() |
||||||
|
|
||||||
val radius = 11 |
val radius = 11 |
||||||
val size = 11 |
val size = 11 |
||||||
val weight: Float = 1.0f / (size * size) |
val weight: Float = 1.0f / (size * size) |
||||||
val matrix = FloatArray(size * size) |
val matrix = FloatArray(size * size) |
||||||
|
|
||||||
for (i in 0..matrix.size - 1) { |
for (i in 0..matrix.size - 1) { |
||||||
matrix[i] = weight |
matrix[i] = weight |
||||||
} |
} |
||||||
|
|
||||||
val kernel = Kernel(radius, size, matrix) |
val kernel = Kernel(radius, size, matrix) |
||||||
val op = ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null) |
val op = ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null) |
||||||
result = op.filter(result, null) |
result = op.filter(result, null) |
||||||
|
|
||||||
return result.getSubimage( |
return result.getSubimage( |
||||||
radius, |
radius, |
||||||
radius, |
radius, |
||||||
result.width - radius * 2, |
result.width - radius * 2, |
||||||
result.height - radius * 2 |
result.height - radius * 2 |
||||||
) |
) |
||||||
} |
} |
||||||
|
|
||||||
fun displayWidth(): Int { |
fun displayWidth(): Int { |
||||||
val window = AppManager.getCurrentFocusedWindow() |
val window = AppManager.focusedWindow |
||||||
if (window != null) { |
if (window != null) { |
||||||
return window.width |
return window.width |
||||||
} |
} |
||||||
return 0 |
return 0 |
||||||
} |
} |
||||||
|
|
||||||
fun displayHeight(): Int { |
fun displayHeight(): Int { |
||||||
val window = AppManager.getCurrentFocusedWindow() |
val window = AppManager.focusedWindow |
||||||
if (window != null) { |
if (window != null) { |
||||||
return window.height |
return window.height |
||||||
} |
} |
||||||
return 0 |
return 0 |
||||||
} |
} |
||||||
|
|
||||||
fun toByteArray(bitmap: BufferedImage) : ByteArray { |
fun toByteArray(bitmap: BufferedImage) : ByteArray { |
||||||
val baos = ByteArrayOutputStream() |
val baos = ByteArrayOutputStream() |
||||||
ImageIO.write(bitmap, "png", baos) |
ImageIO.write(bitmap, "png", baos) |
||||||
return baos.toByteArray() |
return baos.toByteArray() |
||||||
} |
} |
||||||
|
|
||||||
fun cropImage(bitmap: BufferedImage, crop: Rectangle) : BufferedImage { |
fun cropImage(bitmap: BufferedImage, crop: Rectangle) : BufferedImage { |
||||||
val result = BufferedImage(crop.width, crop.height, bitmap.type) |
val result = BufferedImage(crop.width, crop.height, bitmap.type) |
||||||
val graphics = result.createGraphics() |
val graphics = result.createGraphics() |
||||||
graphics.drawImage(bitmap, crop.x, crop.y, crop.width, crop.height, null) |
graphics.drawImage(bitmap, crop.x, crop.y, crop.width, crop.height, null) |
||||||
return result |
return result |
||||||
} |
} |
||||||
|
|
||||||
fun getPreferredWindowSize(desiredWidth: Int, desiredHeight: Int): IntSize { |
fun getPreferredWindowSize(desiredWidth: Int, desiredHeight: Int): IntSize { |
||||||
val screenSize: Dimension = Toolkit.getDefaultToolkit().screenSize |
val screenSize: Dimension = Toolkit.getDefaultToolkit().screenSize |
||||||
val preferredWidth: Int = (screenSize.width * 0.8f).toInt() |
val preferredWidth: Int = (screenSize.width * 0.8f).toInt() |
||||||
val preferredHeight: Int = (screenSize.height * 0.8f).toInt() |
val preferredHeight: Int = (screenSize.height * 0.8f).toInt() |
||||||
val width: Int = if (desiredWidth < preferredWidth) desiredWidth else preferredWidth |
val width: Int = if (desiredWidth < preferredWidth) desiredWidth else preferredWidth |
||||||
val height: Int = if (desiredHeight < preferredHeight) desiredHeight else preferredHeight |
val height: Int = if (desiredHeight < preferredHeight) desiredHeight else preferredHeight |
||||||
return IntSize(width, height) |
return IntSize(width, height) |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue