Load image in separate file and draw in main. Processing 2.0 - image

I'm trying to load the image in a separate class and draw it in the main draw function. I get such an error:
The method image(PImage, float, float) in the type PApplet is not applicable for the arguments (main.image, int, int)
Here is the Image class code:
class Image{
PImage img;
Image(){
img = new PImage();
img = loadImage("test.jpg"); }
}
And here is the main file:
Image img;
void setup(){
img = new Image(this);
}
void draw(){
image(img, 0, 0);
}
Can anyone help please?

The error says it all: Processing doesn't know how to draw your Image class. It doesn't magically know to use the PImage img from your Image class. You have to specifically tell it to use the PImage:
void draw(){
image(img.img, 0, 0);
}
Your naming scheme makes that look a little awkward, but you're referring to the PImage image of your Image named img and telling Processing to draw that instead.
You might want to use a getPImage() function instead of referring to the variable directly. Also note that you're passing the PApplet into the Image constructor using the this keyword, but your Image constructor does not take any arguments.

Related

Displaying UnSplash image URL's on Processing Sketch

I am trying to display a random image URL retrieved via the UnSplash API on a processing screen. There are two issues I think: 1) the url delivered does not have a supported extension such as .jpg etc. It looks like this for example:
https://images.unsplash.com/photo-1672710509828-c971003d3533?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=Mnw0MDM3NDd8MHwxfHJhbmRvbXx8fHx8fHx8fDE2NzQ5MzI4OTM&ixlib=rb-4.0.3&q=80&w=400
I also imagine that an issue might be that the image is not local?
Can anyone help me with this?
Tracy
PImage IMG;
void setup () {
size(1000, 1000);
background (255);
IMG = loadImage("https://images.unsplash.com/photo-1672710509828-c971003d3533?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=Mnw0MDM3NDd8MHwxfHJhbmRvbXx8fHx8fHx8fDE2NzQ5MzI4OTM&ixlib=rb-4.0.3&q=80&w=400");
}
void draw() {
image(IMG, 0, 0);
}
I get an error saying cannot load because it does not have a typical image extension.
Thanks for the help.
One workaround is to add your own URL encoded variable with the sole purpose of ending the URL with ".jpg"
Here's a basic example:
PImage img;
void setup(){
size(400, 600);
noLoop();
String originalURL = "https://images.unsplash.com/photo-1672710509828-c971003d3533?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=Mnw0MDM3NDd8MHwxfHJhbmRvbXx8fHx8fHx8fDE2NzQ5MzI4OTM&ixlib=rb-4.0.3&q=80&w=400";
img = loadImage(originalURL + "&p5=image.jpg");
}
void draw(){
image(img, 0, 0);
}

How to keep image original in QgraphicsView in QT

I have load an image in QGraphicsView, but consider of the size of QGraphicsView scene, I need to scale the image first, then add the scaled image to scene.
e.g. The image original size is 1536*1024, the QGraphicsView size is 500*400, firstly I scale the image like this:
image2D = image2D.scaled( h * P , h, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
myScene->setSceneRect((h * P-w)/2, 0, h * P , h);
pixmapItem = new QGraphicsPixmapItem(image2D);
myScene->addItem(pixmapItem);
myView->setScene(myScene);
And now a problem comes to me, when wheelEvent happends and the QGraphicsView zoom in, the scaled image becomes indistinct while I want it to keep as clear as the original one.
I find a way that I can hold an original copy of image, then when wheelEvent happend just scale the original copy and put it to scene.
But I don't know how to write this code, thanks for help~
or are there any simple methods?
class interactiveView : public QGraphicsView
{
protected:
void wheelEvent(QWheelEvent *event) override;
}
void interactiveView::wheelEvent(QWheelEvent *event)
{
int scrollAmount = event->delta();
xPos = event->pos().x();
yPos = event->pos().y();
scrollAmount > 0 ? zoomIn() : zoomOut();
}
Update:
I find a simple way like this:
just use QGraphicsView::fitInView() to make sure that the image scale is equal to QGraphicsView, and do not need to scale image first.
Therefore the image won't be indistinct when zoom in, and I only need to recall the QGraphicsView::fitInView() to reset to original view instead of using QGraphicsView::resetMatrix()
void myImageWindow::loadImag(int w, int h)
{
pixmapItem->setPixmap(image2D);
//if the scale of image changed
if(image2D.height() != imgHeight_pre){
myView->fitInView(pixmapItem, Qt::KeepAspectRatioByExpanding);
imgHeight_pre = image2D.height();
}
//if the scene of QGraphicsView changed
if(h != sceneHeight_pre){
myView->fitInView(pixmapItem, Qt::KeepAspectRatioByExpanding);
sceneHeight_pre = h;
}
}
void myImageWindow::on_rstImgBtn_clicked()
{
myView->fitInView(pixmapItem, Qt::KeepAspectRatioByExpanding);
}
Scaled image:
becomes indistinct when zoom in:
You can use this method resetMatrix() to reset image
For example:
graphicsView->scale(2, 2);
graphicsView->resetMatrix();
graphicsView->scale(1, 1);

How to resize child QLabel (having a QPixmap) with QHBLayout keeping aspect ratio?

I am dynamically creating a QLabel named label (that has a QPixmap) inside a QHBLayout named layout inside a parent QWidget named by this such that the QLabel image resizes with parent this but maintains the original image aspect ratio.
What I am doing now is the following:
QHBoxLayout* layout = new QHBoxLayout(this);
label = new QLabel(str, this); /* This Label is my concern */
label->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
layout->addWidget(label);
layout->setAlignment(Qt::AlignCenter);
this->setLayout(layout);
layout->setContentsMargins(0,0,0,0);
layout->setSpacing(0);
label->setScaledContents(true);
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
After searching online and as suggested in the accepted answer in Qt layouts - Keep widget aspect ratio while resizing, I even tried creating my own MyLabel class and defining sizeHint() and resizeEvent(QResizeEvent* event) as follows:
QSize MyLabel::sizeHint() const
{
QSize s = size();
lastHeight = s.height();
lastWidth = s.width();
QSize qs = QLabel::sizeHint();
float ratio = std::min(((float)qs.width())/lastWidth, ((float)qs.height())/lastHeight);
s.setWidth(lastWidth*ratio);
s.setHeight(lastHeight*ratio);
return s;
}
void MyLabel::resizeEvent(QResizeEvent* event)
{
QLabel::resizeEvent(event);
if(lastHeight!=height())
{
updateGeometry();
}
}
But the label image still resizes without maintaining aspect ratio.
What am I missing here?
Any help will be highly appreciated.
Thanks in advance.
Try using the subclass of QLabel listed here:
https://stackoverflow.com/a/22618496/999943
Hope that helps.
Try to resize your image instead of QLabel. E.g. by hangling parent widget's resizeEvent and doing something like:
const QPixmap* pixmap = label->pixmap();
if (pixmap->width() >= newGeometry.width())
{
QPixmap scaledPixmap = pixmap->scaledToWidth(newWidth, Qt::SmoothTransformation);
label->setPixmap(scaledPixmap);
}

Processing: PImage converting to different type of object when added to ArrayList

I'm getting a quirky error here.
PImage img;
PImage img2;
PImage img3;
PImage img4;
PImage img5;
PImage img6;
PImage img7;
PImage img8;
PImage img9;
PImage img10;
int count;
int regionHeight;
int regionWidth;
ArrayList images;
void setup(){
//Image of bottle
images = new ArrayList();
img = loadImage("IMG_3763.JPG");
images.add(img);
img2 = loadImage("IMG_3764.JPG");
images.add(img2);
img3 = loadImage("IMG_3765.JPG");
images.add(img3);
img4 = loadImage("IMG_3766.JPG");
images.add(img4);
img5 = loadImage("IMG_3767.JPG");
images.add(img5);
img6 = loadImage("IMG_3768.JPG");
images.add(img6);
img7 = loadImage("IMG_3769.JPG");
images.add(img7);
img8 = loadImage("IMG_3770.JPG");
images.add(img8);
img9 = loadImage("IMG_3771.JPG");
images.add(img9);
img10 = loadImage("IMG_3772.JPG");
images.add(img10);
size(img.width, img.height);
println(img.width);
}
void draw(){
println(images.get(0).width);
}
It seems that any of the images I put into the array are indeed PImages, which is why I can get img.width in setup(), but when I try to do the same with images.get(index) it returns an Object but that Object is not a PImage. I'm not sure I get why the type has changed, it was my understanding that an ArrayList is like a dynamic array with some extra functionality. It should be returning a PImage object, but processing doesn't treat it as such. I verified this with different functions to try and read more into what gets returned, but it really does seem like a different type of object. Am I missing something?
Thanks!
You have to cast the object as a PImage when you get it from an ArrayList
println((PImage)images.get(0).width);
ArrayList stores Objects, it does not know the derived types of the Objects it stores, which is why the cast referenced by #bill_automata fixes things.

Resizing images in GWT and drawing them on canvas

I looked into this thread but the methods are deprecated and for me doesn't even work. I tried to do something similiar but failed. My sample code:
public interface Resources extends ClientBundle{
#Source("images/castle.png")
ImageResource castleIcon();
And the class that draws the image:
private void drawImage() {
Resources res = GWT.create(Resources.class);
final Image icon = new Image(res.castleIcon().getSafeUri());
icon.addLoadHandler(new LoadHandler() {
#Override
public void onLoad(LoadEvent event) {
icon.setPixelSize(100, 80);
}
});
context.drawImage(createImageElement(icon), x - 65, y - 20);
}
private ImageElement createImageElement(Image image) {
return ImageElement.as(image.getElement());
}
I've tried this approach but it fails to render transparent background
Transparency should work fine with PNG on a canvas. Are you sure your image is really transparent? Maybe your PNG is somehow incompatibly with the canvas implementation. Try a proper 24-bit PNG with alpha transparency...

Resources