Merge branch 'besoin8' into 'main'
finished besoin 8 and took care of all errors See merge request pdl-l3/teams/2023/v1/v1d!19
This commit is contained in:
commit
25aa328a2d
2 files changed
+59
-22
No files matched your search
@@ -10,6 +10,7 @@ import java.util.Optional;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.print.attribute.standard.Media;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
@@ -21,6 +22,7 @@ import boofcv.struct.image.Planar;
|
|||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.core.io.InputStreamResource;
|
import org.springframework.core.io.InputStreamResource;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@@ -49,11 +51,27 @@ public class ImageController {
|
|||||||
this.imageDao = imageDao;
|
this.imageDao = imageDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne une erreur de type APPLICATION_JSON
|
||||||
|
*
|
||||||
|
* @param message Le message d'erreur à afficher
|
||||||
|
* @param status La valeur de l'erreur
|
||||||
|
* @return Une ResponseEntity
|
||||||
|
*/
|
||||||
|
public ResponseEntity<?> JSONError(String message, HttpStatus status) {
|
||||||
|
ObjectNode objectNode = mapper.createObjectNode();
|
||||||
|
objectNode.put("code", Integer.toString(status.value()));
|
||||||
|
objectNode.put("message", message);
|
||||||
|
final HttpHeaders httpHeaders = new HttpHeaders();
|
||||||
|
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
return new ResponseEntity<>(objectNode, httpHeaders, status);
|
||||||
|
}
|
||||||
|
|
||||||
@DeleteMapping(value = "/images/{id}")
|
@DeleteMapping(value = "/images/{id}")
|
||||||
public ResponseEntity<?> deleteImage(@PathVariable("id") long id) {
|
public ResponseEntity<?> deleteImage(@PathVariable("id") long id) {
|
||||||
var img = imageDao.retrieve(id);
|
var img = imageDao.retrieve(id);
|
||||||
if (img.isEmpty())
|
if (img.isEmpty())
|
||||||
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
|
return JSONError("Image n°" + id + "doesn't exist", HttpStatus.NOT_FOUND);
|
||||||
imageDao.delete(img.get());
|
imageDao.delete(img.get());
|
||||||
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||||
}
|
}
|
||||||
@@ -63,7 +81,7 @@ public class ImageController {
|
|||||||
String contentType = file.getContentType();
|
String contentType = file.getContentType();
|
||||||
if (contentType == null
|
if (contentType == null
|
||||||
|| (!contentType.equals(MediaType.IMAGE_JPEG_VALUE) && !contentType.equals(MediaType.IMAGE_PNG_VALUE)))
|
|| (!contentType.equals(MediaType.IMAGE_JPEG_VALUE) && !contentType.equals(MediaType.IMAGE_PNG_VALUE)))
|
||||||
return new ResponseEntity<>(HttpStatus.UNSUPPORTED_MEDIA_TYPE);
|
return JSONError("Content type " + contentType + "isn't supported", HttpStatus.UNSUPPORTED_MEDIA_TYPE);
|
||||||
try {
|
try {
|
||||||
Image newImg = new Image(file.getOriginalFilename(), file.getBytes());
|
Image newImg = new Image(file.getOriginalFilename(), file.getBytes());
|
||||||
imageDao.create(newImg);
|
imageDao.create(newImg);
|
||||||
@@ -76,7 +94,7 @@ public class ImageController {
|
|||||||
|
|
||||||
@DeleteMapping(value = "/images")
|
@DeleteMapping(value = "/images")
|
||||||
public ResponseEntity<?> deleteImagesList() {
|
public ResponseEntity<?> deleteImagesList() {
|
||||||
return new ResponseEntity<>(HttpStatus.METHOD_NOT_ALLOWED);
|
return JSONError("Method DELETE not allowed for /images", HttpStatus.METHOD_NOT_ALLOWED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/images", produces = "application/json")
|
@GetMapping(value = "/images", produces = "application/json")
|
||||||
@@ -95,7 +113,8 @@ public class ImageController {
|
|||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/images/{id}", produces = { MediaType.IMAGE_JPEG_VALUE, MediaType.IMAGE_PNG_VALUE })
|
@GetMapping(value = "/images/{id}", produces = { MediaType.IMAGE_JPEG_VALUE, MediaType.IMAGE_PNG_VALUE,
|
||||||
|
"application/json" })
|
||||||
public ResponseEntity<?> getImage(@PathVariable("id") long id,
|
public ResponseEntity<?> getImage(@PathVariable("id") long id,
|
||||||
@RequestParam(required = false) Map<String, String> parameters) {
|
@RequestParam(required = false) Map<String, String> parameters) {
|
||||||
|
|
||||||
@@ -111,16 +130,16 @@ public class ImageController {
|
|||||||
.body(new InputStreamResource(inputStream));
|
.body(new InputStreamResource(inputStream));
|
||||||
}
|
}
|
||||||
// Vérifie la présence du paramètre "algorithm"
|
// Vérifie la présence du paramètre "algorithm"
|
||||||
if (!parameters.containsKey("algorithm"))
|
if (!parameters.containsKey("algorithm")) {
|
||||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
return JSONError("First parameter should be 'algorithm'", HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
String algo = parameters.get("algorithm");
|
String algo = parameters.get("algorithm");
|
||||||
BufferedImage bufImg;
|
BufferedImage bufImg;
|
||||||
try {
|
try {
|
||||||
bufImg = ImageIO.read(new ByteArrayInputStream(image.getData()));
|
bufImg = ImageIO.read(new ByteArrayInputStream(image.getData()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
System.out.println("Error while reading image");
|
return JSONError("There was an internal server error", HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
|
||||||
}
|
}
|
||||||
Planar<GrayU8> input = ConvertBufferedImage.convertFromPlanar(bufImg, null, true, GrayU8.class);
|
Planar<GrayU8> input = ConvertBufferedImage.convertFromPlanar(bufImg, null, true, GrayU8.class);
|
||||||
|
|
||||||
@@ -129,64 +148,78 @@ public class ImageController {
|
|||||||
switch (algo) {
|
switch (algo) {
|
||||||
case "changeLuminosity":
|
case "changeLuminosity":
|
||||||
if (!parameters.containsKey("delta") || parameters.size() != 2)
|
if (!parameters.containsKey("delta") || parameters.size() != 2)
|
||||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
return JSONError("Algorithm 'changeLuminosity' requires one parameter 'delta'(integer)",
|
||||||
|
HttpStatus.BAD_REQUEST);
|
||||||
try {
|
try {
|
||||||
int i = Integer.parseInt(parameters.get("delta"));
|
int i = Integer.parseInt(parameters.get("delta"));
|
||||||
ImageProcessing.changeLuminosity(input, i);
|
ImageProcessing.changeLuminosity(input, i);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
return JSONError("Parameter 'delta' should be an integer", HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "histogram":
|
case "histogram":
|
||||||
if (parameters.size() != 1)
|
if (parameters.size() != 1)
|
||||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
return JSONError("Algorithm 'histogram' doesn't require any parameters", HttpStatus.BAD_REQUEST);
|
||||||
ImageProcessing.histogram(input);
|
ImageProcessing.histogram(input);
|
||||||
break;
|
break;
|
||||||
case "colorFilter":
|
case "colorFilter":
|
||||||
if (!parameters.containsKey("hue") || parameters.size() != 2)
|
if (!parameters.containsKey("hue") || parameters.size() != 2)
|
||||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
return JSONError("Algorithm 'colorFilter' requires one parameter 'hue'(integer)",
|
||||||
|
HttpStatus.BAD_REQUEST);
|
||||||
try {
|
try {
|
||||||
int i = Integer.parseInt(parameters.get("hue"));
|
int i = Integer.parseInt(parameters.get("hue"));
|
||||||
|
if (i < 0) {
|
||||||
|
return JSONError("Parameter 'hue' should be an integer between 0 and 360",
|
||||||
|
HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
ImageProcessing.colorFilter(i, input);
|
ImageProcessing.colorFilter(i, input);
|
||||||
// hue entre 0 et 360?
|
// hue entre 0 et 360?
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
return JSONError("Parameter 'hue' should be an integer between 0 and 360",
|
||||||
|
HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "meanFilter":
|
case "meanFilter":
|
||||||
if (!parameters.containsKey("size") || parameters.size() != 2)
|
if (!parameters.containsKey("size") || parameters.size() != 2)
|
||||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
return JSONError("Algorithm 'meanFilter' requires one parameter 'size'(positive odd integer)",
|
||||||
|
HttpStatus.BAD_REQUEST);
|
||||||
try {
|
try {
|
||||||
int i = Integer.parseInt(parameters.get("size"));
|
int i = Integer.parseInt(parameters.get("size"));
|
||||||
if (i % 2 == 0)
|
if (i % 2 == 0)
|
||||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
return JSONError("Parameter 'size' should be a positive odd integer",
|
||||||
|
HttpStatus.BAD_REQUEST);
|
||||||
Planar<GrayU8> clone = input.clone();
|
Planar<GrayU8> clone = input.clone();
|
||||||
ImageProcessing.meanFilter(clone, input, i);
|
ImageProcessing.meanFilter(clone, input, i);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
return JSONError("Parameter 'size' should be a positive odd integer",
|
||||||
|
HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "gaussienFilter":
|
case "gaussienFilter":
|
||||||
if (!parameters.containsKey("size") || parameters.size() != 2)
|
if (!parameters.containsKey("size") || parameters.size() != 2)
|
||||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
return JSONError("Algorithm 'gaussienFilter' requires one parameter 'size'(positive odd integer)",
|
||||||
|
HttpStatus.BAD_REQUEST);
|
||||||
try {
|
try {
|
||||||
int i = Integer.parseInt(parameters.get("size"));
|
int i = Integer.parseInt(parameters.get("size"));
|
||||||
if (i % 2 == 0)
|
if (i % 2 == 0)
|
||||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
return JSONError("Parameter 'size' should be a positive odd integer",
|
||||||
|
HttpStatus.BAD_REQUEST);
|
||||||
Planar<GrayU8> clone = input.clone();
|
Planar<GrayU8> clone = input.clone();
|
||||||
ImageProcessing.gaussienFilter(clone, input, i);
|
ImageProcessing.gaussienFilter(clone, input, i);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
return JSONError("Parameter 'size' should be a positive odd integer",
|
||||||
|
HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "contours":
|
case "contours":
|
||||||
if (parameters.size() != 1)
|
if (parameters.size() != 1)
|
||||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
return JSONError("Algorithm 'contours' doesn't require any parameters", HttpStatus.BAD_REQUEST);
|
||||||
Planar<GrayU8> clone = input.clone();
|
Planar<GrayU8> clone = input.clone();
|
||||||
ImageProcessing.gradientImageSobel(clone, input);
|
ImageProcessing.gradientImageSobel(clone, input);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
return JSONError("Requested algorithm doesn't exist", HttpStatus.BAD_REQUEST);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// transforme l'image en quelque chose que le navigateur puisse lire
|
// transforme l'image en quelque chose que le navigateur puisse lire
|
||||||
@@ -195,7 +228,7 @@ public class ImageController {
|
|||||||
try {
|
try {
|
||||||
ImageIO.write(bufImg, image.getMediaType().getSubtype(), baos);
|
ImageIO.write(bufImg, image.getMediaType().getSubtype(), baos);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
return JSONError("There was an internal server error", HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
byte[] imageData = baos.toByteArray();
|
byte[] imageData = baos.toByteArray();
|
||||||
InputStream inputStream = new ByteArrayInputStream(imageData);
|
InputStream inputStream = new ByteArrayInputStream(imageData);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package pdl.backend;
|
|||||||
|
|
||||||
import boofcv.struct.image.GrayU8;
|
import boofcv.struct.image.GrayU8;
|
||||||
import boofcv.struct.image.Planar;
|
import boofcv.struct.image.Planar;
|
||||||
|
import boofcv.alg.color.ColorHsv;
|
||||||
|
|
||||||
public class ImageProcessing {
|
public class ImageProcessing {
|
||||||
|
|
||||||
@@ -213,6 +214,9 @@ public class ImageProcessing {
|
|||||||
* @param input L'image à modifier
|
* @param input L'image à modifier
|
||||||
*/
|
*/
|
||||||
public static void colorFilter(int hue, Planar<GrayU8> input) {
|
public static void colorFilter(int hue, Planar<GrayU8> input) {
|
||||||
|
if (hue < 0 || hue > 360) {
|
||||||
|
throw new IllegalArgumentException("Hue doit être compris entre 0 et 360");
|
||||||
|
}
|
||||||
for (int j = 0; j < input.height; j++) {
|
for (int j = 0; j < input.height; j++) {
|
||||||
for (int i = 0; i < input.width; i++) {
|
for (int i = 0; i < input.width; i++) {
|
||||||
float[] hsv = new float[3];
|
float[] hsv = new float[3];
|
||||||
|
|||||||
Reference in new issue
Block a user