Convert Image File to a Negative - kotlin

I want to get the negative of a specific Image based on following command-line input.
-in xyz.png -out xyz_negative.png
The files loaded are stored in a specific folder.
Here is what I was/am trying to do so far.
Read a png file
Calculate RGB values for each pixel
Calculate Negative RGB Values
Set new RGB Values for png file to get the negative
I am kinda stuck on the last step since the new .png ist not the negative. Here is my code, if anybody could help me or point me in the right direction I would be much obliged.
import java.awt.Color
import java.io.File
import javax.imageio.ImageIO
fun main(args: Array<String>) {
if (args.isNotEmpty()) {
val myFile = File(
"/Users/xyz/IdeaProjects/Seam Carving/Seam Carving/task/${args[1]}")
val importedImage = ImageIO.read(myFile)
for (x in 0 until importedImage.width) {
for (y in 0 until importedImage.height) {
val pixel = importedImage.getRGB(x, y)
var color = Color(pixel, true)
val redNegative = 255 - color.red
val greenNegative = 255 - color.green
val blueNegative = 255 - color.blue
color = Color(redNegative, blueNegative, greenNegative)
importedImage.setRGB(x, y, color.rgb)
}
}
ImageIO.write(importedImage, "png", File("/Users/xyz/IdeaProjects/Seam Carving/Seam Carving/task/${args[3]}"))
}
}
What its supposed to look like:
What my image looks like

Related

Kotlin lets-plot: minimal example

I would like to write a completely minimal example of lets-plot, which just saves png and doesn't use any frontend. For this, I created a "helloworld" Kotlin project in IntelliJ IDEA. Then I added Maven dependency org.jetbrains.lets-plot:lets-plot-common:2.1.0. Now if I try to import jetbrains.letsPlot.letsPlot, I get the error "Unresolved reference: letsPlot". Thus, the question is how to write the most minimal lets-plot example, without using any frontend and Gradle.
The right dependencies are org.jetbrains.lets-plot:lets-plot-kotlin-jvm:3.0.2 (for API) and org.jetbrains.lets-plot:lets-plot-image-export:2.1.0 (to be able to export to raster). Now it works, and the resulting image in lets-plot-images directory.
The code:
import jetbrains.letsPlot.export.ggsave
import jetbrains.letsPlot.geom.geomPoint
import jetbrains.letsPlot.letsPlot
fun main() {
val xs = listOf(0, 0.5, 1, 2)
val ys = listOf(0, 0.25, 1, 4)
val data = mapOf<String, Any>("x" to xs, "y" to ys)
val fig = letsPlot(data) + geomPoint(
color = "dark-green",
size = 4.0
) { x = "x"; y = "y" }
ggsave(fig, "plot.png")
}
The resulting image:

How to write a string to clipboard (Windows OS) with a Kotlin/Native application?

I'm very new to Kotlin and making a command line .exe, on Windows using Kotlin/Native. The application should read from a text file and print on screen, line by line. When it reaches the last line of the file, it should put it in the clipboard.
aFile.txt looks something like this:
one
two
three
...
...
the last line
and the code read.kt (Kotlin/Native) I have so far is this:
import kotlinx.cinterop.*
import platform.posix.*
fun main(args: Array<String>) {
if (args.size != 1) {
println("Usage: read.exe <file.txt>")
return
}
val fileName = args[0]
val file = fopen(fileName, "r")
if (file == null) {
perror("cannot open input file $fileName")
return
}
try {
memScoped {
val bufferLength = 64 * 1024
val buffer = allocArray<ByteVar>(bufferLength)
do {
val nextLine = fgets(buffer, bufferLength, file)?.toKString()
if (nextLine == null || nextLine.isEmpty()) break
print("${nextLine}")
} while (true)
}
} finally {
fclose(file)
}
}
The code above prints each line on the screen, but how do I write the string "the last line" in the computer's clipboard? I'm looking for a native (not Java) solution if that's possible.
Thank you very much.
Update:
Obviously, this is not the solution I was looking for, but I don't understand yet what are they talking about here (https://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setclipboarddata).
As a temporary fix, I was able to get what I needed using system(), echo and clip with code like this:
system("echo ${nextLine} | clip")
print("${nextLine}")
Try the following:
import java.awt.Toolkit
import java.awt.datatransfer.Clipboard
import java.awt.datatransfer.StringSelection
fun setClipboard(s: String) {
val selection = StringSelection(s)
val clipboard: Clipboard = Toolkit.getDefaultToolkit().systemClipboard
clipboard.setContents(selection, selection)
}
In Windows, you can work with the Clipboard through WinAPI, as you can see there. The reference says, that you got to use functions from the winuser.h header. This header is included in windows.h, as far as I know, so it is in your platform.windows.* package. You can approve it by checking Kotlin/Native repository files.
To clarify, what I meant, I wrote this small example of platform.windows.* usage. You can add this function to your code, and call it when you got to copy some string.
import platform.windows.*
fun toClipboard(lastLine:String?){
val len = lastLine!!.length + 1
val hMem = GlobalAlloc(GMEM_MOVEABLE, len.toULong())
memcpy(GlobalLock(hMem), lastLine.cstr, len.toULong())
GlobalUnlock(hMem)
val hwnd = HWND_TOP
OpenClipboard(hwnd)
EmptyClipboard()
SetClipboardData(CF_TEXT, hMem)
CloseClipboard()
}

How do I get a pixel color from an imageView using Kotlin?

I'm trying to get the color of a pixel from my imageView by hovering over it, but my application keeps crashing.
Ive tried using code from stackoverflow threads but most of them are old and outdated and some just didn't work for me.
Tried using Canvas also but it also didn't work.
my code is:
#SuppressLint("ClickableViewAccessibility")
private fun getPixelInfo() {
val pixelInfoText = findViewById<TextView>(R.id.pixelInfoText)
val imageView = findViewById<ImageView>(R.id.imageView)
imageView.bringToFront()
imageView.setOnTouchListener { _, event ->
val x = event.x.toInt()
val y = event.y.toInt()
if (event.action == MotionEvent.ACTION_MOVE) {
pixelInfoText.text = "$x $y"
}
true
}
My application keeps crashing,
but it should set the textView text to be like
"X: 250 Y: 500 COLOR: #F8AC4D"
Found the way to do it:
val bitmap = Bitmap.createBitmap(layout.width, layout.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
layout.draw(canvas)
val color = bitmap.getPixel(x, y)

How does UV mapping work with surfacetool in Godot?

I'm coding a terrain generator in Godot. I generate the Mesh using SurfaceTool and triangle strips. The geometry works fine — but the UV mapping doesn't, as each triangle repeats the texture instead of the full mesh covering the texture once:
Normalizing the UV-Coordinates to fit into the 0,0 - 1,1 dimensions is what should work, but doesn't, as it makes only one pair of triangles have the full texture and the rest is blank:
extends MeshInstance
export var terrain_width = 16
export var terrain_depth = 16
export var terrain_height = 1
export var terrain_scale = 1
#Noise Generation
var terrain_noise = OpenSimplexNoise.new()
var terrain_heightmap = ImageTexture.new()
var terrain_texture = Texture.new()
var terrain_material = SpatialMaterial.new()
var terrain_mesh = Mesh.new()
var surfacetool = SurfaceTool.new()
func _ready():
generate_heightmap()
generate_mesh()
func generate_heightmap():
#Setup the noise
terrain_noise.seed = randi()
terrain_noise.octaves = 4
terrain_noise.period = 20.0
terrain_noise.persistence = 0.8
#Make the texture
terrain_heightmap.create_from_image(terrain_noise.get_image(terrain_width+1, terrain_depth+1))
terrain_texture = terrain_heightmap
func generate_mesh():
#Set the material texture to the heightmap
terrain_material.albedo_texture = terrain_texture
# This is where the uv-mapping occurs, via the add_uv function
for z in range(0,terrain_depth):
surfacetool.begin(Mesh.PRIMITIVE_TRIANGLE_STRIP)
for x in range(0,terrain_width):
surfacetool.add_uv(Vector2((terrain_width-x)/terrain_width,z/terrain_depth))
surfacetool.add_vertex(Vector3((terrain_width-x)*terrain_scale, terrain_noise.get_noise_2d(x,z)*terrain_height*terrain_scale, z*terrain_scale))
surfacetool.add_uv(Vector2((terrain_width-x)/terrain_width,(z+1)/terrain_depth))
surfacetool.add_vertex(Vector3((terrain_width-x)*terrain_scale, terrain_noise.get_noise_2d(x,z+1)*terrain_height*terrain_scale, (z+1)*terrain_scale))
surfacetool.generate_normals()
surfacetool.index()
surfacetool.commit(terrain_mesh)
#Set the texture and mesh on the MeshInstance
self.material_override = terrain_material
self.set_mesh(terrain_mesh)
self.set_surface_material(0, terrain_texture)
I expect each triangle to cover only the corresponding coordinates in the texture.
It seems as if each triangle is considered as a separate surface.
You have lots of integer divisions there. There are many ways to fix that. Here's a quick one: Just add .0 after your exported variable's default values:
export var terrain_width = 16.0
export var terrain_depth = 16.0
export var terrain_height = 1.0
export var terrain_scale = 1.0
And here's a more explicit way:
export(float) var terrain_width = 16
export(float) var terrain_depth = 16
export(float) var terrain_height = 1
export(float) var terrain_scale = 1
Assuming you don't have any other bugs, this should fix the issue.

PDFBox not clean tmp files after convertToImage method

I use the PDFBox function, such as convertToImage, everything works fine, but PDFBox does not clear the temporary files after the conversion. In my system in the directory for temporary files "/tmp" there are many files such us +~JF132216249314633400.tmp, they are deleted only after restarting my application, but when the application continues to work, temporary files are not deleted.
PDFBox version - 1.8.15
when I use this
page.convertToImage(BufferedImage.TYPE_INT_RGB, 300)
the PDFbox library creates tmp files such as "+~JF132216249314633400.tmp"
my method:
def splitPdfToImages(file: File): List[File] = {
val document = PDDocument.load(file)
val pages = (for (i <- 0 until document.getNumberOfPages)
yield document.getDocumentCatalog.getAllPages.get(i).asInstanceOf[PDPage]).toList
val imgFiles = pages.zipWithIndex.map { case (page, i) =>
val baos = IOUtils.createBAOS
ImageIO.write(page.convertToImage(BufferedImage.TYPE_INT_RGB, 300), "jpg", baos)
val bais = IOUtils.createBAIS(baos.toByteArray)
try {
val img = Image.fromStream(bais)
implicit val writer = JpegWriter().withCompression(100)
val tmpFile = File.createTempFile(s"""${file.getName.split("\\.").head}_$i""", file.getName.split("\\.").last)
img.output(tmpFile)
} finally {
baos.close()
bais.close()
}
}
document.close()
imgFiles
}
Please help me to solve this issue.