Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a2eeaf3
fromBytes function in ImageTools. current plan - deprecate loadFromFi…
ShaharMS May 24, 2025
1bda5ad
added js image loading technique,notice that they are spin-looping, s…
ShaharMS May 24, 2025
4739514
support for RAW and JPEG in load function, CI should fail
ShaharMS May 24, 2025
1cc1997
further integration of new from methods: fromURL and fromFile. need t…
ShaharMS May 24, 2025
911acbc
Js & format lib methods for exporting images to different formats (bm…
ShaharMS May 26, 2025
49c3cb2
Added `To`, `ToBytes` and their respective methods/property with inte…
ShaharMS May 27, 2025
b0188e8
FromFramework, copied framework IO to a seperate file
ShaharMS May 27, 2025
46fd612
To methods for frameworks, integration into ImageIO
ShaharMS May 27, 2025
e9e316f
Removed ImageTools.from/to references, as well as the functions.
ShaharMS May 27, 2025
ddf4736
Changelog and stuff
ShaharMS May 28, 2025
a9bfa1e
some little fixes here and there + renames
ShaharMS May 28, 2025
02b5bc9
Merge pull request #50 from ShaharMS/qol/better-image-loading
ShaharMS May 28, 2025
f967864
Starting the new generator
ShaharMS May 28, 2025
ee5ac92
First steps towards something simple
ShaharMS May 28, 2025
20fcf57
Detector now basically fully works, onto generation
ShaharMS May 29, 2025
141fd35
progress on generation
ShaharMS May 29, 2025
8984bef
Major progress on generator
ShaharMS May 29, 2025
a348462
generated test classes are pretty much done
ShaharMS May 29, 2025
f4a9e53
Holy moly lots of progress! well the generator + detector are pretty …
ShaharMS Jun 4, 2025
af4c312
There are still some problems with the generator, but i might leave i…
ShaharMS Jun 4, 2025
e19d173
A more intelligent generator, also a more comfortable gen + run metho…
ShaharMS Jun 5, 2025
60abe5b
formatting changes to output files + better generator
ShaharMS Jun 5, 2025
d18cfb0
Standardized the way function signatres are written (void never decla…
ShaharMS Jun 8, 2025
a608a43
Basically all unit tests generated, also improved generator + detecto…
ShaharMS Jun 8, 2025
a5359c8
Regenerate tests one more time to have a more cohesive structure. Tes…
ShaharMS Jun 9, 2025
61eba74
more unit tests, need to resolve stuff with byte array
ShaharMS Jun 11, 2025
f61fcbc
Partial tests for color, bytearray fixed
ShaharMS Jun 11, 2025
504bc5c
some more tests
ShaharMS Jun 11, 2025
8ff82f2
done with tests for Color, fix some tests as well
ShaharMS Jun 14, 2025
fb66ad8
More tests, need to fix the test resolve bar sometime in the future
ShaharMS Jun 15, 2025
3d660d9
Some tests for MathTools
ShaharMS Jun 15, 2025
b146b7f
More tests...
ShaharMS Jun 29, 2025
2ef9058
Some more tests
ShaharMS Nov 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"ARGB",
"Bezier",
"BGRA",
"bitmapdata",
"bitmask",
"blit",
"Blitting",
Expand All @@ -33,6 +34,7 @@
"fceil",
"ffloor",
"Flixel",
"flxsprite",
"frameworking",
"fround",
"grayscale",
Expand All @@ -45,6 +47,7 @@
"haxeui",
"hxml",
"ifies",
"imagedata",
"interp",
"Ints",
"kernal",
Expand Down
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
# 2.1.1

### `Image.hx`
- **Added `Image.copyImageFrom`**

### `vision.ds`
- **Added `ImageFormat.JPEG`, `ImageFormat.VISION`**

### `vision.tools`
- **Added `ImageTools.loadFromFile` (synchronous version)**
- **Added `ImageTools.loadFromBytes`**
- **Added `ImageTools.loadFromURL`**
- **Added `ImageTools.exportToBytes`**
- **Added `ImageTools.exportToFile`**
- **Deprecated `ImageTools.saveToFile` in favor of `ImageTools.exportToFile`**

### `vision.formats`
- **New Subdirectory inside the `vision` package for cleaner image format conversions**
- **Added `ImageIO` - reads/writes images from/to different formats/frameworks**
- **Added support for `jpeg` encoding for non-js platforms using `format`**

# 2.1.0

### `Vision.hx`
Expand Down
2 changes: 2 additions & 0 deletions src/VisionMain.hx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package;

import vision.formats.ImageIO;
import vision.algorithms.SimpleHough;
import vision.ds.Matrix2D;
import vision.ds.Color;
Expand Down Expand Up @@ -35,6 +36,7 @@ using vision.tools.MathTools;
printImage(image);
printImage(image.filterForColorChannel(RED));


#if simple_tests
printSectionDivider("Simple image manipulation");
start = haxe.Timer.stamp();
Expand Down
175 changes: 99 additions & 76 deletions src/vision/Vision.hx

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions src/vision/algorithms/BilinearInterpolation.hx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package vision.algorithms;

import vision.ds.Color;
import vision.tools.ImageTools;
import vision.exceptions.OutOfBounds;
import vision.ds.Image;
import vision.tools.MathTools.*;

Expand Down
3 changes: 0 additions & 3 deletions src/vision/algorithms/Cramer.hx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ package vision.algorithms;

import vision.exceptions.InvalidCramerSetup;
import vision.exceptions.InvalidCramerCoefficientsMatrix;
import vision.tools.MathTools;
import vision.ds.Matrix2D;
import haxe.ds.Vector;
import vision.ds.Array2D;

/**
Solve a system of linear equations using Cramer's rule.
Expand Down
4 changes: 2 additions & 2 deletions src/vision/algorithms/Gauss.hx
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class Gauss {
return kernel;
}
@:deprecated("Gaussian.createKernelOfSize() is deprecated. use Gaussian.create2DKernelOfSize() instead")
public static function createKernelOfSize(size:Int, sigma:Int) {
public static function createKernelOfSize(size:Int, sigma:Int):Array2D<Float> {
return create2DKernelOfSize(size, sigma);
}

Expand Down Expand Up @@ -172,7 +172,7 @@ class Gauss {
return kernel;
}

public static function fastBlur(image:Image, size:Int, sigma:Float) {
public static function fastBlur(image:Image, size:Int, sigma:Float):Image {
var preprocessed = image.clone();
#if vision_quiet
if (size <= 0) size = -size;
Expand Down
4 changes: 1 addition & 3 deletions src/vision/algorithms/ImageHashing.hx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ package vision.algorithms;

import haxe.Int64;
import vision.ds.Matrix2D;
import vision.tools.ImageTools;
import vision.ds.ByteArray;
import vision.ds.Image;
import vision.ds.ImageResizeAlgorithm;

using vision.tools.MathTools;

Expand All @@ -32,7 +30,7 @@ class ImageHashing {
}
}

return clone.toBytes();
return clone.exportToBytes();
}

public static function phash(image:Image):ByteArray {
Expand Down
3 changes: 1 addition & 2 deletions src/vision/algorithms/KMeans.hx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ using vision.tools.MathTools;
using vision.tools.ArrayTools;

class KMeans {
public static function generateClustersUsingConvergence<T>(values:Array<T>, clusterAmount:Int, distanceFunction:(T, T) -> Float,
averageFunction:Array<T>->T):Array<Array<T>> {
public static function generateClustersUsingConvergence<T>(values:Array<T>, clusterAmount:Int, distanceFunction:(T, T) -> Float, averageFunction:Array<T>->T):Array<Array<T>> {
var clusterCenters = pickElementsAtRandom(values, clusterAmount, true);

// We don't use clusterAmount in case where the image doesnt have enough distinct colors to satisfy
Expand Down
4 changes: 2 additions & 2 deletions src/vision/algorithms/Laplace.hx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import vision.ds.Image;

class Laplace {

public static function convolveWithLaplacianOperator(image:Image, positive:Bool) {
public static function convolveWithLaplacianOperator(image:Image, positive:Bool):Image {
var edgeColors:Image = new Image(image.width, image.height);

for (i in 0...image.width) {
Expand All @@ -28,7 +28,7 @@ class Laplace {
return edgeColors;
}

public static function laplacianOfGaussian(image:Image, kernelSize:GaussianKernelSize, sigma:Float, threshold:Float, positive:Bool) {
public static function laplacianOfGaussian(image:Image, kernelSize:GaussianKernelSize, sigma:Float, threshold:Float, positive:Bool):Image {
var returned = new Image(image.width, image.height);
var blurred = Vision.gaussianBlur(image.clone().removeView(), sigma, kernelSize);
var imageToProcess:Image;
Expand Down
65 changes: 32 additions & 33 deletions src/vision/algorithms/Perwitt.hx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ using vision.tools.MathTools;
* by [Shahar Marcus](https://www.github.com/ShaharMS)
*/
class Perwitt {
public static function convolveWithPerwittOperator(image:Image) {
public static function convolveWithPerwittOperator(image:Image):Image {
var edgeColors:Image = new Image(image.width, image.height);
var maxGradient = -1;

Expand Down Expand Up @@ -39,7 +39,7 @@ class Perwitt {
if (gradient > maxGradient) maxGradient = gradient;

final rgb:Int = Std.int(gradient * (255 / maxGradient));
//turn into ARGB
// turn into ARGB
edgeColors.setPixel(i, j, 0xff000000 | (rgb << 16) | (rgb << 8) | rgb);
}
}
Expand All @@ -62,6 +62,7 @@ class Perwitt {
}

// If you came here for the explanation of the algorithm, Congrats! learning is fun :D

/**
What does this algorithm do?
Basically, it takes 9 pixels chunks each time it performs a calculation, and tries to see how different the
Expand All @@ -82,38 +83,36 @@ class Perwitt {
Now, if this value is greater than the threshold, then we declare it an edge. now, were gonna do the same thing
for all chunks of the image, and from top to bottom too if needed.
**/
public static function detectEdges(image:Image, threshold:Float) {


var edges = new Image(image.width, image.height, Color.fromRGBA(0, 0, 0));
var blackAndWhite = Vision.grayscale(image.clone());
for (x in 0...blackAndWhite.width) {
for (y in 0...blackAndWhite.height) {
var neighbors = [
blackAndWhite.getSafePixel(x - 1, y - 1),
blackAndWhite.getSafePixel(x, y - 1),
blackAndWhite.getSafePixel(x + 1, y - 1),
blackAndWhite.getSafePixel(x - 1, y),
blackAndWhite.getSafePixel(x, y),
blackAndWhite.getSafePixel(x + 1, y),
blackAndWhite.getSafePixel(x - 1, y + 1),
blackAndWhite.getSafePixel(x, y + 1),
blackAndWhite.getSafePixel(x + 1, y + 1)
];
final perwittCalculationIterationLTR = neighbors[0].red * -1
+ neighbors[3].red * -1 + neighbors[6].red * -1 + neighbors[2].red * 1 + neighbors[5].red * 1 + neighbors[8].red * 1;
if (Math.abs(perwittCalculationIterationLTR) > threshold) {
edges.setPixel(x, y, Color.fromRGBA(255, 255, 255));
continue;
}
final perwittCalculationIterationTTB = neighbors[0].red * -1
+ neighbors[1].red * -1 + neighbors[2].red * -1 + neighbors[6].red * 1 + neighbors[7].red * 1 + neighbors[8].red * 1;
if (Math.abs(perwittCalculationIterationTTB) > threshold) {
edges.setPixel(x, y, Color.fromRGBA(255, 255, 255));
continue;
}
public static function detectEdges(image:Image, threshold:Float):Image {
var edges = new Image(image.width, image.height, Color.fromRGBA(0, 0, 0));
var blackAndWhite = Vision.grayscale(image.clone());
for (x in 0...blackAndWhite.width) {
for (y in 0...blackAndWhite.height) {
var neighbors = [
blackAndWhite.getSafePixel(x - 1, y - 1),
blackAndWhite.getSafePixel(x, y - 1),
blackAndWhite.getSafePixel(x + 1, y - 1),
blackAndWhite.getSafePixel(x - 1, y),
blackAndWhite.getSafePixel(x, y),
blackAndWhite.getSafePixel(x + 1, y),
blackAndWhite.getSafePixel(x - 1, y + 1),
blackAndWhite.getSafePixel(x, y + 1),
blackAndWhite.getSafePixel(x + 1, y + 1)
];
final perwittCalculationIterationLTR = neighbors[0].red * -1
+ neighbors[3].red * -1 + neighbors[6].red * -1 + neighbors[2].red * 1 + neighbors[5].red * 1 + neighbors[8].red * 1;
if (Math.abs(perwittCalculationIterationLTR) > threshold) {
edges.setPixel(x, y, Color.fromRGBA(255, 255, 255));
continue;
}
final perwittCalculationIterationTTB = neighbors[0].red * -1
+ neighbors[1].red * -1 + neighbors[2].red * -1 + neighbors[6].red * 1 + neighbors[7].red * 1 + neighbors[8].red * 1;
if (Math.abs(perwittCalculationIterationTTB) > threshold) {
edges.setPixel(x, y, Color.fromRGBA(255, 255, 255));
continue;
}
}
return edges;
}
return edges;
}
}
6 changes: 3 additions & 3 deletions src/vision/algorithms/Radix.hx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class Radix {
/**
Sorts an array of `Int`s / `UInt`s / `Int64` using **Radix Sort**.
**/
public static overload extern inline function sort(main:Array<Int>) {
overload extern public static inline function sort(main:Array<Int>):Array<Int> {

var negatives = [], positives = [];
for (i in 0...main.length) {
Expand Down Expand Up @@ -113,7 +113,7 @@ class Radix {
return main = negatives.concat(positives);
}

public static overload extern inline function sort(main:Array<UInt>) {
overload extern public static inline function sort(main:Array<UInt>):Array<UInt> {
// Find the maximum number to know the number of digits
final max = getMax(main, main.length);
var exp = 1;
Expand All @@ -129,7 +129,7 @@ class Radix {
return main;
}

public static overload extern inline function sort(main:Array<Int64>) {
overload extern public static inline function sort(main:Array<Int64>):Array<Int64> {

var negatives = [], positives = [];
for (i in 0...main.length) {
Expand Down
2 changes: 1 addition & 1 deletion src/vision/algorithms/RobertsCross.hx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import vision.ds.Image;
**/
class RobertsCross {

public static function convolveWithRobertsCross(image:Image) {
public static function convolveWithRobertsCross(image:Image):Image {
var edgeColors:Image = new Image(image.width, image.height);
var maxGradient = -1;

Expand Down
2 changes: 1 addition & 1 deletion src/vision/algorithms/SimpleHough.hx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class SimpleHough {
return rays;
}

public static function mapLines(image:Image, rays:Array<Ray2D>) {
public static function mapLines(image:Image, rays:Array<Ray2D>):Image {
for (ray in rays) {
image.drawRay2D(ray, Color.CYAN);
}
Expand Down
2 changes: 1 addition & 1 deletion src/vision/algorithms/SimpleLineDetector.hx
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ class SimpleLineDetector {
return lines;
}

static extern inline function p(x:Int = 0, y:Int = 0) {
static extern inline function p(x:Int = 0, y:Int = 0):Int16Point2D {
return new Int16Point2D(x, y);
}

Expand Down
4 changes: 2 additions & 2 deletions src/vision/algorithms/Sobel.hx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ using vision.tools.MathTools;
by [Shahar Marcus](https://www.github.com/ShaharMS)
**/
class Sobel {
public static function convolveWithSobelOperator(image:Image) {
public static function convolveWithSobelOperator(image:Image):Image {
var edgeColors:Image = new Image(image.width, image.height);
var maxGradient = -1;

Expand Down Expand Up @@ -68,7 +68,7 @@ class Sobel {
If this value is greater than the threshold, then we declare it an edge. now, were gonna do the same thing
for all chunks of the image, and from top to bottom too if needed.
**/
public static function detectEdges(image:Image, threshold:Float) {
public static function detectEdges(image:Image, threshold:Float):Image {
final edges = new Image(image.width, image.height, Color.fromRGBA(0, 0, 0));
final blackAndWhite = Vision.grayscale(image.clone());
for (x in 0...blackAndWhite.width) {
Expand Down
3 changes: 2 additions & 1 deletion src/vision/ds/Array2D.hx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package vision.ds;

import haxe.iterators.ArrayIterator;
#if !vision_fancy_array_access
/**
A 2D array, faster than an `Array<Array<T>>`.
Expand Down Expand Up @@ -106,7 +107,7 @@ class Array2D<T> {

`(x, y)...(x + 5, y) -> (x, y + 1)...(x + 5, y + 1) -> (x, y + 2)...`
**/
public inline function iterator() {
public inline function iterator():ArrayIterator<T> {
return inner.iterator();
}

Expand Down
Loading
Loading