connect to csharp
This commit is contained in:
parent
0261b94820
commit
b88ff96b32
16 changed files with 336 additions and 63 deletions
1
.env
Normal file
1
.env
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
ASSET_PATH_RO="/mnt/c/Users/Formulatrix/Documents/Explorations/tiles1705/"
|
||||||
18
.gitignore
vendored
18
.gitignore
vendored
|
|
@ -1,2 +1,20 @@
|
||||||
/target
|
/target
|
||||||
*.png
|
*.png
|
||||||
|
bin/
|
||||||
|
obj/
|
||||||
|
/packages/
|
||||||
|
riderModule.iml
|
||||||
|
/_ReSharper.Caches/
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Rider ignored files
|
||||||
|
/contentModel.xml
|
||||||
|
/projectSettingsUpdater.xml
|
||||||
|
/modules.xml
|
||||||
|
/.idea.WebApplication1.iml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
|
|
||||||
7
Cargo.lock
generated
7
Cargo.lock
generated
|
|
@ -80,6 +80,12 @@ dependencies = [
|
||||||
"litrs",
|
"litrs",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dotenv"
|
||||||
|
version = "0.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fast_image_resize"
|
name = "fast_image_resize"
|
||||||
version = "5.1.4"
|
version = "5.1.4"
|
||||||
|
|
@ -412,6 +418,7 @@ dependencies = [
|
||||||
name = "stitcher"
|
name = "stitcher"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"dotenv",
|
||||||
"fast_image_resize",
|
"fast_image_resize",
|
||||||
"futures",
|
"futures",
|
||||||
"png",
|
"png",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ edition = "2024"
|
||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
dotenv = "0.15"
|
||||||
png = "0.17.16"
|
png = "0.17.16"
|
||||||
tokio = { version = "1.46.0", features = ["full"] }
|
tokio = { version = "1.46.0", features = ["full"] }
|
||||||
fast_image_resize = "5.1.4"
|
fast_image_resize = "5.1.4"
|
||||||
|
|
|
||||||
21
README.md
Normal file
21
README.md
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
Stitch only png image
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
0. Install nix
|
||||||
|
```
|
||||||
|
curl -fsSL https://install.determinate.systems/nix | sh -s -- install --determinate
|
||||||
|
```
|
||||||
|
Follow the installation guide. For complete information: https://github.com/DeterminateSystems/nix-installer
|
||||||
|
|
||||||
|
Then run this (and wait `:)`)
|
||||||
|
```
|
||||||
|
nix-shell --pure
|
||||||
|
```
|
||||||
|
you can `exit` from the shell later.
|
||||||
|
|
||||||
|
1. finally
|
||||||
|
```
|
||||||
|
cd StitchImg/
|
||||||
|
cargo run --release & dotnet run -c Release
|
||||||
|
```
|
||||||
35
StitchImg/ImageController.cs
Executable file
35
StitchImg/ImageController.cs
Executable file
|
|
@ -0,0 +1,35 @@
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace StitchImg;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/image")]
|
||||||
|
public class ImageController : ControllerBase
|
||||||
|
{
|
||||||
|
[HttpPost("generate")]
|
||||||
|
public async Task<IActionResult> Generate([FromBody] ImageSpecification specification)
|
||||||
|
{
|
||||||
|
var serverIp = "127.0.0.1";
|
||||||
|
var port = 8080;
|
||||||
|
|
||||||
|
var tcpClient = new TcpClient();
|
||||||
|
await tcpClient.ConnectAsync(serverIp, port);
|
||||||
|
NetworkStream networkStream = tcpClient.GetStream();
|
||||||
|
var writer = new BinaryWriter(networkStream);
|
||||||
|
|
||||||
|
string rect = specification.CanvasRect;
|
||||||
|
byte[] rectBytes = Encoding.UTF8.GetBytes(rect);
|
||||||
|
writer.Write((ushort)rectBytes.Length);
|
||||||
|
writer.Write(rectBytes);
|
||||||
|
writer.Write(specification.CropOffset[0]);
|
||||||
|
writer.Write(specification.CropSize[0]);
|
||||||
|
writer.Write(specification.CropOffset[1]);
|
||||||
|
writer.Write(specification.CropSize[1]);
|
||||||
|
writer.Write(specification.OutputScale);
|
||||||
|
writer.Flush();
|
||||||
|
|
||||||
|
return File( networkStream, "image/png");
|
||||||
|
}
|
||||||
|
}
|
||||||
9
StitchImg/ImageSpecification.cs
Executable file
9
StitchImg/ImageSpecification.cs
Executable file
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace StitchImg;
|
||||||
|
|
||||||
|
public class ImageSpecification
|
||||||
|
{
|
||||||
|
public string CanvasRect { get; set; }
|
||||||
|
public IReadOnlyList<float> CropOffset { get; set; }
|
||||||
|
public IReadOnlyList<float> CropSize { get; set; }
|
||||||
|
public float OutputScale { get; set; }
|
||||||
|
}
|
||||||
51
StitchImg/Program.cs
Executable file
51
StitchImg/Program.cs
Executable file
|
|
@ -0,0 +1,51 @@
|
||||||
|
using Microsoft.OpenApi.Models;
|
||||||
|
using Newtonsoft.Json.Serialization;
|
||||||
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
builder.Services.AddControllers()
|
||||||
|
.AddNewtonsoftJson(options =>
|
||||||
|
{
|
||||||
|
options.SerializerSettings.ContractResolver = new DefaultContractResolver
|
||||||
|
{
|
||||||
|
NamingStrategy = new SnakeCaseNamingStrategy()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
|
builder.Services.AddSwaggerGen(c =>
|
||||||
|
{
|
||||||
|
c.SchemaFilter<SnakeCaseSchemaFilter>();
|
||||||
|
});
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseHttpsRedirection();
|
||||||
|
app.MapControllers();
|
||||||
|
app.Run();
|
||||||
|
|
||||||
|
public class SnakeCaseSchemaFilter : ISchemaFilter
|
||||||
|
{
|
||||||
|
private readonly SnakeCaseNamingStrategy _namingStrategy = new();
|
||||||
|
|
||||||
|
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
|
||||||
|
{
|
||||||
|
if (schema.Properties == null) return;
|
||||||
|
|
||||||
|
var newProps = new Dictionary<string, OpenApiSchema>();
|
||||||
|
foreach (var prop in schema.Properties)
|
||||||
|
{
|
||||||
|
var snakeName = _namingStrategy.GetPropertyName(prop.Key, false);
|
||||||
|
newProps[snakeName] = prop.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
schema.Properties = newProps;
|
||||||
|
}
|
||||||
|
}
|
||||||
41
StitchImg/Properties/launchSettings.json
Executable file
41
StitchImg/Properties/launchSettings.json
Executable file
|
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:53404",
|
||||||
|
"sslPort": 44379
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "http://localhost:5031",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "https://localhost:7060;http://localhost:5031",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
StitchImg/StitchImg.csproj
Executable file
19
StitchImg/StitchImg.csproj
Executable file
|
|
@ -0,0 +1,19 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="DotImaging.BitmapInterop" Version="5.2.0" />
|
||||||
|
<PackageReference Include="DotImaging.Image" Version="5.2.0" />
|
||||||
|
<PackageReference Include="DotImaging.IO" Version="5.2.0" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.15"/>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
8
StitchImg/appsettings.Development.json
Executable file
8
StitchImg/appsettings.Development.json
Executable file
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
StitchImg/appsettings.json
Executable file
9
StitchImg/appsettings.json
Executable file
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
||||||
16
WebApplication1.sln
Executable file
16
WebApplication1.sln
Executable file
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StitchImg", "StitchImg\StitchImg.csproj", "{3AE7CACB-316B-4A70-B15C-537A285ADCDA}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{3AE7CACB-316B-4A70-B15C-537A285ADCDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{3AE7CACB-316B-4A70-B15C-537A285ADCDA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{3AE7CACB-316B-4A70-B15C-537A285ADCDA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{3AE7CACB-316B-4A70-B15C-537A285ADCDA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
7
global.json
Executable file
7
global.json
Executable file
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"sdk": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"rollForward": "latestMinor",
|
||||||
|
"allowPrerelease": false
|
||||||
|
}
|
||||||
|
}
|
||||||
20
shell.nix
Normal file
20
shell.nix
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
{ pkgs ? import
|
||||||
|
(builtins.fetchTarball {
|
||||||
|
url = "https://github.com/NixOS/nixpkgs/archive/refs/heads/nixos-24.11.tar.gz";
|
||||||
|
})
|
||||||
|
{ }
|
||||||
|
}:
|
||||||
|
|
||||||
|
pkgs.mkShell {
|
||||||
|
name = "dotnet-rust-env";
|
||||||
|
|
||||||
|
buildInputs = [
|
||||||
|
pkgs.dotnetCorePackages.sdk_8_0
|
||||||
|
pkgs.rustup
|
||||||
|
];
|
||||||
|
|
||||||
|
shellHook = ''
|
||||||
|
export PATH=$HOME/.cargo/bin:$PATH
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
||||||
136
src/main.rs
136
src/main.rs
|
|
@ -3,67 +3,80 @@ use fr::{PixelType, ResizeAlg, ResizeOptions, Resizer, images::Image};
|
||||||
use futures::future::join_all;
|
use futures::future::join_all;
|
||||||
use std::{
|
use std::{
|
||||||
cell::UnsafeCell,
|
cell::UnsafeCell,
|
||||||
|
env,
|
||||||
io::Cursor,
|
io::Cursor,
|
||||||
io::Write,
|
|
||||||
ops::{Bound, RangeBounds},
|
ops::{Bound, RangeBounds},
|
||||||
|
path::Path,
|
||||||
};
|
};
|
||||||
use tokio::fs;
|
use tokio::{
|
||||||
// use tokio::net::TcpListener;
|
fs,
|
||||||
|
io::{AsyncReadExt, AsyncWriteExt},
|
||||||
|
};
|
||||||
|
use tokio::{io::BufReader, net::TcpListener};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
// let listener = TcpListener::bind("127.0.0.1:8080").await?;
|
dotenv::dotenv().ok();
|
||||||
// println!("Server listening on port 8080");
|
let listener = TcpListener::bind("127.0.0.1:8080").await?;
|
||||||
//
|
println!("Server listening on port 8080");
|
||||||
// loop {
|
loop {
|
||||||
// let (socket, _) = listener.accept().await?;
|
let (socket, _) = listener.accept().await?;
|
||||||
// tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
// if let Err(e) = handle_client(socket).await {
|
let timer_start = std::time::Instant::now();
|
||||||
// eprintln!("Error: {}", e);
|
if let Err(e) = handle_client(socket).await {
|
||||||
// }
|
println!("Error: {}", e);
|
||||||
// });
|
} else {
|
||||||
// }
|
println!("Data sent");
|
||||||
// }
|
}
|
||||||
//
|
let duration = timer_start.elapsed();
|
||||||
// async fn handle_client(socket: tokio::net::TcpStream) -> Result<(), Box<dyn std::error::Error>> {
|
println!("Operation completed in: {:.2?}", duration);
|
||||||
// // let file = std::fs::File::create("raw_image_123.png").unwrap();
|
});
|
||||||
// let offset_x = 0.5;
|
}
|
||||||
// let size_x = 0.5;
|
}
|
||||||
// let offset_y = 0.5;
|
|
||||||
// let size_y = 0.5;
|
|
||||||
// let rect = "A1:AE55";
|
|
||||||
// let scale = 0.4;
|
|
||||||
//
|
|
||||||
// resize_image(
|
|
||||||
// &mut socket.into_std().unwrap(),
|
|
||||||
// rect,
|
|
||||||
// scale,
|
|
||||||
// offset_x,
|
|
||||||
// offset_y,
|
|
||||||
// size_x,
|
|
||||||
// size_y,
|
|
||||||
// )
|
|
||||||
// .await;
|
|
||||||
//
|
|
||||||
// Ok(())
|
|
||||||
// }
|
|
||||||
let timer_start = std::time::Instant::now();
|
|
||||||
|
|
||||||
let file = std::fs::File::create("raw_image_123.png").unwrap();
|
async fn handle_client(
|
||||||
let offset_x = 0.5;
|
mut socket: tokio::net::TcpStream,
|
||||||
let size_x = 0.5;
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let offset_y = 0.5;
|
println!("Incoming request");
|
||||||
let size_y = 0.5;
|
let mut reader = BufReader::new(&mut socket);
|
||||||
let rect = "A1:AE55";
|
|
||||||
let scale = 0.4;
|
|
||||||
|
|
||||||
resize_image(file, rect, scale, offset_x, offset_y, size_x, size_y).await;
|
let rect_len = reader.read_u16_le().await?;
|
||||||
|
let mut rect_buf = vec![0u8; rect_len as usize];
|
||||||
|
reader.read_exact(&mut rect_buf).await?;
|
||||||
|
let rect = String::from_utf8(rect_buf)?;
|
||||||
|
|
||||||
|
let offset_x = reader.read_f32_le().await?;
|
||||||
|
let size_x = reader.read_f32_le().await?;
|
||||||
|
let offset_y = reader.read_f32_le().await?;
|
||||||
|
let size_y = reader.read_f32_le().await?;
|
||||||
|
let scale = reader.read_f32_le().await?;
|
||||||
|
|
||||||
|
println!("Parsed values:");
|
||||||
|
println!(" rect: {rect}");
|
||||||
|
println!(" offset_x: {offset_x}");
|
||||||
|
println!(" size_x: {size_x}");
|
||||||
|
println!(" offset_y: {offset_y}");
|
||||||
|
println!(" size_y: {size_y}");
|
||||||
|
println!(" scale: {scale}");
|
||||||
|
|
||||||
|
let mut result_buffer = Vec::new();
|
||||||
|
stitch_and_resize_image(
|
||||||
|
&mut result_buffer,
|
||||||
|
&rect,
|
||||||
|
scale,
|
||||||
|
offset_x,
|
||||||
|
offset_y,
|
||||||
|
size_x,
|
||||||
|
size_y,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
socket.write_all(&result_buffer).await.unwrap();
|
||||||
|
|
||||||
let duration = timer_start.elapsed();
|
|
||||||
println!("Operation completed in: {:.2?}", duration);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
async fn resize_image(
|
async fn stitch_and_resize_image(
|
||||||
out: impl Write,
|
out: &mut Vec<u8>,
|
||||||
rect: &str,
|
rect: &str,
|
||||||
scale: f32,
|
scale: f32,
|
||||||
offset_x: f32,
|
offset_x: f32,
|
||||||
|
|
@ -125,8 +138,6 @@ async fn resize_image(
|
||||||
}
|
}
|
||||||
let results = join_all(handles).await;
|
let results = join_all(handles).await;
|
||||||
|
|
||||||
let writer = std::io::BufWriter::new(out);
|
|
||||||
|
|
||||||
let start_x = (offset_x * canvas_width as f32).trunc() as usize;
|
let start_x = (offset_x * canvas_width as f32).trunc() as usize;
|
||||||
let start_y = (offset_y * canvas_height as f32).trunc() as usize;
|
let start_y = (offset_y * canvas_height as f32).trunc() as usize;
|
||||||
let end_x = ((offset_x + size_x) * canvas_width as f32).trunc() as usize;
|
let end_x = ((offset_x + size_x) * canvas_width as f32).trunc() as usize;
|
||||||
|
|
@ -136,16 +147,15 @@ async fn resize_image(
|
||||||
let crop_height = end_y - start_y;
|
let crop_height = end_y - start_y;
|
||||||
|
|
||||||
let mut encoder = png::Encoder::new(
|
let mut encoder = png::Encoder::new(
|
||||||
writer,
|
Cursor::new(out),
|
||||||
crop_width.try_into().unwrap(),
|
crop_width.try_into().unwrap(),
|
||||||
crop_height.try_into().unwrap(),
|
crop_height.try_into().unwrap(),
|
||||||
);
|
);
|
||||||
encoder.set_color(png::ColorType::Rgb);
|
encoder.set_color(png::ColorType::Rgb);
|
||||||
encoder.set_depth(png::BitDepth::Eight);
|
encoder.set_depth(png::BitDepth::Eight);
|
||||||
|
encoder
|
||||||
println!("Writing img");
|
.write_header()
|
||||||
let mut png_writer = encoder.write_header().unwrap();
|
.unwrap()
|
||||||
png_writer
|
|
||||||
.write_image_data(&crop_rgb_image(
|
.write_image_data(&crop_rgb_image(
|
||||||
&canvas.to_vec(),
|
&canvas.to_vec(),
|
||||||
(actual_size * row_count) as usize,
|
(actual_size * row_count) as usize,
|
||||||
|
|
@ -202,11 +212,11 @@ async fn add_to_canvas(
|
||||||
canvas_height: usize,
|
canvas_height: usize,
|
||||||
) {
|
) {
|
||||||
let mut resizer = Resizer::new();
|
let mut resizer = Resizer::new();
|
||||||
let base_path = "/mnt/c/Users/Formulatrix/Documents/Explorations/WebApplication1/tiles1705/";
|
let env = &env::var("ASSET_PATH_RO").unwrap();
|
||||||
let filename = format!("{}{}{}.png", base_path, number_to_column(i), j);
|
let img_path = Path::new(&env);
|
||||||
// println!("{filename}");
|
let filename = format!("{}{}.png", number_to_column(i), j);
|
||||||
|
|
||||||
let data = Cursor::new(fs::read(filename).await.unwrap()); // .unwrap();
|
let data = Cursor::new(fs::read(img_path.join(filename)).await.unwrap());
|
||||||
let decoder = png::Decoder::new(data);
|
let decoder = png::Decoder::new(data);
|
||||||
let mut reader = decoder.read_info().unwrap();
|
let mut reader = decoder.read_info().unwrap();
|
||||||
let mut buf = vec![0; reader.output_buffer_size()];
|
let mut buf = vec![0; reader.output_buffer_size()];
|
||||||
|
|
@ -225,7 +235,7 @@ async fn add_to_canvas(
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
place_image(
|
place_image(
|
||||||
&canvas,
|
canvas,
|
||||||
canvas_width,
|
canvas_width,
|
||||||
canvas_height,
|
canvas_height,
|
||||||
&img.into_vec(),
|
&img.into_vec(),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue