Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #36497 > unrolled thread

BufferedImage and int[] array

Started by"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
First post2017-04-21 08:28 -0700
Last post2017-04-24 11:25 -0500
Articles 19 — 3 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  BufferedImage and int[] array "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-04-21 08:28 -0700
    Re: BufferedImage and int[] array Eric Douglas <e.d.programmer@gmail.com> - 2017-04-21 08:54 -0700
      Re: BufferedImage and int[] array "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-04-21 09:03 -0700
        Re: BufferedImage and int[] array Eric Douglas <e.d.programmer@gmail.com> - 2017-04-21 10:41 -0700
          Re: BufferedImage and int[] array Eric Douglas <e.d.programmer@gmail.com> - 2017-04-21 10:46 -0700
          Re: BufferedImage and int[] array "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-04-21 11:13 -0700
            Re: BufferedImage and int[] array Eric Douglas <e.d.programmer@gmail.com> - 2017-04-21 12:12 -0700
            Re: BufferedImage and int[] array Eric Douglas <e.d.programmer@gmail.com> - 2017-04-21 13:24 -0700
              Re: BufferedImage and int[] array "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-04-21 13:37 -0700
                Re: BufferedImage and int[] array "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-04-21 13:40 -0700
                Re: BufferedImage and int[] array Eric Douglas <e.d.programmer@gmail.com> - 2017-04-21 13:54 -0700
                  Re: BufferedImage and int[] array "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-04-21 13:59 -0700
                Re: BufferedImage and int[] array Eric Douglas <e.d.programmer@gmail.com> - 2017-04-21 13:58 -0700
                  Re: BufferedImage and int[] array "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-04-21 14:06 -0700
    Re: BufferedImage and int[] array Knute Johnson <nospam@rabbitbrush.frazmtn.com> - 2017-04-22 11:28 -0500
      Re: BufferedImage and int[] array "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-04-24 07:33 -0700
        Re: BufferedImage and int[] array Eric Douglas <e.d.programmer@gmail.com> - 2017-04-24 08:04 -0700
      Re: BufferedImage and int[] array "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-04-24 08:17 -0700
        Re: BufferedImage and int[] array Knute Johnson <nospam@rabbitbrush.frazmtn.com> - 2017-04-24 11:25 -0500

#36497 — BufferedImage and int[] array

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2017-04-21 08:28 -0700
SubjectBufferedImage and int[] array
Message-ID<5a1d0bab-5ae7-45a1-9c8f-344183ed48ba@googlegroups.com>
I'm using JDK 1.8 on Linux.

I have a PNG file which is ARGB when I load it in GIMP, and would like
to obtain an array of int pixels to alter its contents directly from
within my app.

I am able to obtain byte[], but I don't know how to translate it to
int[] for direct 4-byte access per pixel.

I read on Stack Overflow that they aren't compatible unless the img
created is ARGB as well, meaning the ImageIO.read(new File("myfile.png"))
may have returned only a 24-bit RGB image, and not with the transparency
layer/channel.  I also see on Stack Overflow that this may be a known
bug as other people have had this same issue in the past.

If true, how would I force it to read in and create it as an ARGB layer
even if it doesn't think the alpha channel is there?  And if I cannot,
do I read it in in whatever format it's in, create a second image of the
same size but with 32-bit ARGB for the color depth, and then do some kind
of BitBlt operation to paint the pixel bits into the other image?

I come from a Win32 GDI and C/C++ background where I handle most of the
low-level drawing through custom functions.  I'm not sure what the
equivalent operation is in Java.

-----
I am basically trying to load an image, obtain an array to the raw
pixel data so I can manipulate each pixel directly in various ways,
including a colorize() algorithm, invert(), putBorder(), etc.

Thank you,
Rick C. Hodgin

[toc] | [next] | [standalone]


#36498

FromEric Douglas <e.d.programmer@gmail.com>
Date2017-04-21 08:54 -0700
Message-ID<4f6d8eef-73e3-45f6-94fc-4ccb530ddd8c@googlegroups.com>
In reply to#36497
On Friday, April 21, 2017 at 11:29:07 AM UTC-4, Rick C. Hodgin wrote:
> -----
> I am basically trying to load an image, obtain an array to the raw
> pixel data so I can manipulate each pixel directly in various ways,
> including a colorize() algorithm, invert(), putBorder(), etc.
> 
> Thank you,
> Rick C. Hodgin

I've never had a problem dealing with images and only using byte[] array.  I didn't even know images could or should be referenced as int[] array.  So I'd need specifics on what you're trying to do, either some code you wrote that's not working and/or the stackoverflow post you mentioned.  Otherwise I can only assume you're looking for this:
https://stackoverflow.com/questions/12154090/creating-8-bit-image-from-byte-array

[toc] | [prev] | [next] | [standalone]


#36499

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2017-04-21 09:03 -0700
Message-ID<0f806bdc-aa93-4897-bb9f-8373ffd16175@googlegroups.com>
In reply to#36498
On Friday, April 21, 2017 at 11:54:16 AM UTC-4, Eric Douglas wrote:
> On Friday, April 21, 2017 at 11:29:07 AM UTC-4, Rick C. Hodgin wrote:
> > -----
> > I am basically trying to load an image, obtain an array to the raw
> > pixel data so I can manipulate each pixel directly in various ways,
> > including a colorize() algorithm, invert(), putBorder(), etc.
> > 
> > Thank you,
> > Rick C. Hodgin
> 
> I've never had a problem dealing with images and only using byte[] array.  I didn't even know images could or should be referenced as int[] array.  So I'd need specifics on what you're trying to do, either some code you wrote that's not working and/or the stackoverflow post you mentioned.  Otherwise I can only assume you're looking for this:
> https://stackoverflow.com/questions/12154090/creating-8-bit-image-from-byte-array

The underlying data in the byte[] array should already be in that
exact int[] format.  If I could cast the byte[] array into an int[],
then I could reference it as an int 4-bytes at a time.

Basically, I'm trying to do that without having to convert it as
the Stack Overflow link above indicates, because I want to be able
to access the byte[] data as that int[] form at any time.

Here's a reference on Stack Overflow:

    http://stackoverflow.com/questions/20852641/bufferedimage-int-pixels-and-rendering-how-do-they-work-they-work-together

It uses this code:

    int[] pixels = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();

That apparently works when you have a 4-byte color depth, but if it's
not 4-bytes (32-bit) it doesn't work.  That's understandable, so I
need to know how to convert whatever format is loaded with the
IoImage.read() to then create a BufferedImage that is in 4-byte form?

Thank you,
Rick C. Hodgin

[toc] | [prev] | [next] | [standalone]


#36500

FromEric Douglas <e.d.programmer@gmail.com>
Date2017-04-21 10:41 -0700
Message-ID<903d6ec5-ab8e-4e87-9581-13ff803bf461@googlegroups.com>
In reply to#36499
On Friday, April 21, 2017 at 12:03:19 PM UTC-4, Rick C. Hodgin wrote:
> That apparently works when you have a 4-byte color depth, but if it's
> not 4-bytes (32-bit) it doesn't work.  That's understandable, so I
> need to know how to convert whatever format is loaded with the
> IoImage.read() to then create a BufferedImage that is in 4-byte form?
> 
> Thank you,
> Rick C. Hodgin

Here again it would help if you have some source code that's not working to debug.  I'm going to guess the image bytes you have are file bytes.
          
          final byte[] contents;
          InputStream myFileInputStream;
          File myImgFile = new File("c:/image.png");
          myFileInputStream = new FileInputStream(myImgFile);
          contents = new byte[myFileInputStream.available()];
          myFileInputStream.read(contents);
          myFileInputStream.close();

Then you can get an image from those bytes.

          ByteArrayInputStream myByteArrayInputStream;
          BufferedImage myBufferedImage = null;
          myByteArrayInputStream = new ByteArrayInputStream(contents);
          final MemoryCacheImageInputStream mciis = new MemoryCacheImageInputStream(myByteArrayInputStream);
          myBufferedImage = ImageIO.read(mciis);

Then you can grab the int[] reference.
          int[] pixels = ((DataBufferInt)myBufferedImage.getRaster().getDataBuffer()).getData(); 

There is no casting the byte[].  I think that stackoverflow you linked explains the int[] well.  What else are you missing?

[toc] | [prev] | [next] | [standalone]


#36501

FromEric Douglas <e.d.programmer@gmail.com>
Date2017-04-21 10:46 -0700
Message-ID<bd0382cd-8a6b-4cde-8b5d-a213645bb2c4@googlegroups.com>
In reply to#36500
On Friday, April 21, 2017 at 1:41:28 PM UTC-4, Eric Douglas wrote:
>           final byte[] contents;
>           InputStream myFileInputStream;
>           File myImgFile = new File("c:/image.png");
>           myFileInputStream = new FileInputStream(myImgFile);
>           contents = new byte[myFileInputStream.available()];
>           myFileInputStream.read(contents);
>           myFileInputStream.close();

While using .available() to read the entire stream often just works on local files, or files embedded in the jar, there is a more reliable stream method.

     public static byte[] getStreamBytes(final InputStream is) throws IOException {
          final ByteArrayOutputStream baos = new ByteArrayOutputStream();
          int bytesRead = 0;
          while (bytesRead > -1) {
               bytesRead = Math.max(is.available(), 1);
               final byte[] buf = new byte[bytesRead];
               bytesRead = is.read(buf);
               if (bytesRead > 0) {
                    baos.write(buf, 0, bytesRead);
               }
          }
          baos.flush();
          baos.close();
          return baos.toByteArray();
     }

[toc] | [prev] | [next] | [standalone]


#36502

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2017-04-21 11:13 -0700
Message-ID<a2ae1966-1dc0-4019-8286-16a5825ba843@googlegroups.com>
In reply to#36500
On Friday, April 21, 2017 at 1:41:28 PM UTC-4, Eric Douglas wrote:
> On Friday, April 21, 2017 at 12:03:19 PM UTC-4, Rick C. Hodgin wrote:
> > That apparently works when you have a 4-byte color depth, but if it's
> > not 4-bytes (32-bit) it doesn't work.  That's understandable, so I
> > need to know how to convert whatever format is loaded with the
> > IoImage.read() to then create a BufferedImage that is in 4-byte form?
> > 
> > Thank you,
> > Rick C. Hodgin
> 
> Here again it would help if you have some source code that's not working
> to debug.  I'm going to guess the image bytes you have are file bytes.

I'm using NetBeans 8.0.2 on Linux, and here's my source code:

    http://www.libsf.org:8990/projects/LIB/repos/libsf/browse/king/keyboard_driver/gui

It didn't save the project apparently, so you can't just load it, but
here is the exact source file:

    Line 180:
    pixels = ((DataBufferInt)img.getRaster().getDataBuffer()).getData();
    http://www.libsf.org:8990/projects/LIB/repos/libsf/browse/king/keyboard_driver/gui/src/gui/BufferedImage3.java

Throws an exception saying DataBufferByte cannot be cast to DataBufferInt.

>           final byte[] contents;
>           InputStream myFileInputStream;
>           File myImgFile = new File("c:/image.png");
>           myFileInputStream = new FileInputStream(myImgFile);
>           contents = new byte[myFileInputStream.available()];
>           myFileInputStream.read(contents);
>           myFileInputStream.close();
> 
> Then you can get an image from those bytes.
> 
>           ByteArrayInputStream myByteArrayInputStream;
>           BufferedImage myBufferedImage = null;
>           myByteArrayInputStream = new ByteArrayInputStream(contents);
>           final MemoryCacheImageInputStream mciis = new MemoryCacheImageInputStream(myByteArrayInputStream);
>           myBufferedImage = ImageIO.read(mciis);
> 
> Then you can grab the int[] reference.
>           int[] pixels = ((DataBufferInt)myBufferedImage.getRaster().getDataBuffer()).getData(); 
> 
> There is no casting the byte[].  I think that stackoverflow you linked
> explains the int[] well.  What else are you missing?

The way I have applied it (using another Stack Overflow link, and one
of several that I've looked at) doesn't work.

Thank you,
Rick C. Hodgin

[toc] | [prev] | [next] | [standalone]


#36503

FromEric Douglas <e.d.programmer@gmail.com>
Date2017-04-21 12:12 -0700
Message-ID<7ef3a82b-48c9-43d5-82e8-d3510612bce5@googlegroups.com>
In reply to#36502
On Friday, April 21, 2017 at 2:13:45 PM UTC-4, Rick C. Hodgin wrote:
> 
> The way I have applied it (using another Stack Overflow link, and one
> of several that I've looked at) doesn't work.
> 
> Thank you,
> Rick C. Hodgin

Well, if you Google that problem, the first result looks like they did the same thing.
http://stackoverflow.com/questions/15839223/java-awt-image-databufferbyte-cannot-be-cast-to-java-awt-image-databufferint

So I test your code with a transparent PNG and it does show the ImageIO.read() statement returned a type 6.
http://docs.oracle.com/javase/8/docs/api/constant-values.html#java.awt.image.BufferedImage.TYPE_3BYTE_BGR

So if you want to manipulate ints it seems you need a TYPE_INT (1,2,3,4).
So what do you get if you convert it?
Insert this code right after the ImageIO.read().
               final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
               final GraphicsDevice gd = ge.getDefaultScreenDevice();
               final GraphicsConfiguration gc = gd.getDefaultConfiguration();
               final BufferedImage newimg = gc.createCompatibleImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
               // Draw the image on to the buffered image
               final Graphics2D myImageGraphics = newimg.createGraphics();
               myImageGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
               myImageGraphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
               myImageGraphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
               myImageGraphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
               myImageGraphics.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
               myImageGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
               myImageGraphics.fillRect(0, 0, img.getWidth(), img.getHeight());
               myImageGraphics.setComposite(AlphaComposite.SrcOver);
               myImageGraphics.drawImage(img, 0, 0, null);
               myImageGraphics.dispose();
               img = newimg;

and of course modify your imports
import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

[toc] | [prev] | [next] | [standalone]


#36504

FromEric Douglas <e.d.programmer@gmail.com>
Date2017-04-21 13:24 -0700
Message-ID<125e8758-3bf6-453b-8c5c-cadd339a0ebf@googlegroups.com>
In reply to#36502
On Friday, April 21, 2017 at 2:13:45 PM UTC-4, Rick C. Hodgin wrote:
>     http://www.libsf.org:8990/projects/LIB/repos/libsf/browse/king/keyboard_driver/gui/src/gui/BufferedImage3.java
> 

I tested with the change I suggested and it got past your error so I assume that fixes the problem you're asking about here, though I crashed on the ImageIO.write() because I didn't have valid file names in there.
I put in valid local files to test that.  The first write worked fine, the other 2 failed, so there appears to be something wrong with your rgba() method.
With a real lack of comments in your code I'm not sure what each section is trying to accomplish.
Taking a guess your invert method wants to turn the image upside down, I googled that and found this working code.

     public void invert(final BufferedImage img) {
          WritableRaster raster = img.getRaster();
          int h = raster.getHeight();
          int w = raster.getWidth();
          int x0 = raster.getMinX();
          int y0 = raster.getMinY();
          for (int x = x0; x < x0 + w; x++){
              for (int y = y0; y < y0 + h / 2; y++){
                  int[] pix1 = new int[4];
                  pix1 = raster.getPixel(x, y, pix1);
                  int[] pix2 = new int[4];
                  pix2 = raster.getPixel(x, y0 + h - 1 - (y - y0), pix2);
                  raster.setPixel(x, y, pix2);
                  raster.setPixel(x, y0 + h - 1 - (y - y0), pix1);
              }
          }
          return;

Either I'm missing something, or you need to fix your argb method, or you need to get rid of that and change the other methods to do something like the invert code here.

[toc] | [prev] | [next] | [standalone]


#36505

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2017-04-21 13:37 -0700
Message-ID<e09756ab-7d8b-49ea-a529-6d6b71a8554f@googlegroups.com>
In reply to#36504
On Friday, April 21, 2017 at 4:24:47 PM UTC-4, Eric Douglas wrote:
> With a real lack of comments in your code I'm not sure what each
> section is trying to accomplish.
> Taking a guess your invert method wants to turn the image upside down,
> I googled that and found this working code.

That code was all written last night and when I ran into the issue
with reading in a transparent enabled PNG file and it losing the
alpha channel I sort of stopped.

The algorithm is inverting the color.  This line reverses the color
of each pixel color channel:

    Line 275:
    pixels[offset] = rgba(255 - red, 255 - grn, 255 - blu, 0);
    http://www.libsf.org:8990/projects/LIB/repos/libsf/browse/king/keyboard_driver/gui/src/gui/BufferedImage3.java

The 255 - red computes the inverted color of the red channel, and
it repeats for green, blue, and sets the alpha channel to 0, which
is a bug and should be using the originally derived alp value on
line 220, once it's copied down into that function. :-)

I'll look at your solution.  I'm really thinking I don't need to
do anything other than load in the PNG as a 3-byte BGR format,
and then create a second PNG in the 4-byte ARGB format, and then
obtain WritableRaster objects and draw the image from one to the
other, which should handle the translation, and then delete the
3-byte BGR version.

Do you feel so inclined to write code to test that method out?
I only ask because you've been far more helpful than I would've
expected someone to be on Usenet. :-)  I plan on working on it
tonight.  I've only programmed in Java one time previously back
in 2011 on a project used to automate tests on hardware:

    Office Productivity Benchmark
    https://github.com/RickCHodgin/opbm

A lot of code written mostly from May-July 2011.  I'm sure it
has lots of errors in it, but I was on my own in trying to do
everything.  I used Stack Overflow and the javadoc help files.

That one was written in NetBeans 8.0 I believe.

Thank you,
Rick C. Hodgin

[toc] | [prev] | [next] | [standalone]


#36506

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2017-04-21 13:40 -0700
Message-ID<d485eb00-0827-4136-95a3-f8b6bbbd54a0@googlegroups.com>
In reply to#36505
On Friday, April 21, 2017 at 4:37:47 PM UTC-4, Rick C. Hodgin wrote:
> ...I've only programmed in Java one time previously back
> in 2011 on a project used to automate tests on hardware:
> 
>     Office Productivity Benchmark
>     https://github.com/RickCHodgin/opbm
> 
> A lot of code written mostly from May-July 2011.  I'm sure it
> has lots of errors in it, but I was on my own in trying to do
> everything.  I used Stack Overflow and the javadoc help files.

I don't mean lots of errors, but I mean that I did lots of things
in non-standard ways, or ways other Java devs would not code in.

I did it that way from my predominately C/C++ background.

> That one was written in NetBeans 8.0 I believe.

Thank you,
Rick C. Hodgin

[toc] | [prev] | [next] | [standalone]


#36507

FromEric Douglas <e.d.programmer@gmail.com>
Date2017-04-21 13:54 -0700
Message-ID<76664d4e-bc0e-4f10-9262-171f4db6d6fe@googlegroups.com>
In reply to#36505
On Friday, April 21, 2017 at 4:37:47 PM UTC-4, Rick C. Hodgin wrote:
> That code was all written last night and when I ran into the issue
> with reading in a transparent enabled PNG file and it losing the
> alpha channel I sort of stopped.
> 
> The algorithm is inverting the color.  This line reverses the color
> of each pixel color channel:
> 

I believe I did figure out the invert was trying to invert the colors not the horizontal.  Change the pixels line in the invert to pass the actual alpha:
pixels[offset] = rgba(255 - red, 255 - grn, 255 - blu, (rgba & 0xff000000) >> 24);

Then change the rgba method to just add them.
return(red + (grn << 8) + (blu << 16) + (alp << 24));

[toc] | [prev] | [next] | [standalone]


#36509

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2017-04-21 13:59 -0700
Message-ID<b3ba7166-4895-4114-aeff-557aaffb5a46@googlegroups.com>
In reply to#36507
On Friday, April 21, 2017 at 4:54:43 PM UTC-4, Eric Douglas wrote:
> On Friday, April 21, 2017 at 4:37:47 PM UTC-4, Rick C. Hodgin wrote:
> > That code was all written last night and when I ran into the issue
> > with reading in a transparent enabled PNG file and it losing the
> > alpha channel I sort of stopped.
> > 
> > The algorithm is inverting the color.  This line reverses the color
> > of each pixel color channel:
> > 
> 
> I believe I did figure out the invert was trying to invert the colors not the horizontal.  Change the pixels line in the invert to pass the actual alpha:
> pixels[offset] = rgba(255 - red, 255 - grn, 255 - blu, (rgba & 0xff000000) >> 24);
> 
> Then change the rgba method to just add them.
> return(red + (grn << 8) + (blu << 16) + (alp << 24));

LOL!  Well, they should be OR operations, not AND:

    return (red | (grn << 8) | (blu << 16) | <alp << 24);

I code like that all of the time.  I know what I'm intending, but it
literally gets translated out of my fingers differently than what's
in my mind.  It's very frustrating at times.  A symptom of dylsexia
and the associated family of the spectrum. :-)

Thank you,
Rick C. Hodgin

[toc] | [prev] | [next] | [standalone]


#36508

FromEric Douglas <e.d.programmer@gmail.com>
Date2017-04-21 13:58 -0700
Message-ID<adecf5a8-bfd0-4806-841f-de44908625bc@googlegroups.com>
In reply to#36505
On Friday, April 21, 2017 at 4:37:47 PM UTC-4, Rick C. Hodgin wrote:
> 
> Do you feel so inclined to write code to test that method out?
> I only ask because you've been far more helpful than I would've
> expected someone to be on Usenet. :-)  I plan on working on it
> tonight.  I've only programmed in Java one time previously back
> in 2011 on a project used to automate tests on hardware:

We won't "do your homework for you" but I do love a good puzzle.

> 
>     Office Productivity Benchmark
>     https://github.com/RickCHodgin/opbm
> 
> A lot of code written mostly from May-July 2011.  I'm sure it
> has lots of errors in it, but I was on my own in trying to do
> everything.  I used Stack Overflow and the javadoc help files.
> 
> That one was written in NetBeans 8.0 I believe.
> 
I use Eclipse.  We have 2 developers in a small company.  I write all the Java.

[toc] | [prev] | [next] | [standalone]


#36510

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2017-04-21 14:06 -0700
Message-ID<996b4e12-7e54-446e-917c-0ce10c970cf3@googlegroups.com>
In reply to#36508
On Friday, April 21, 2017 at 4:58:24 PM UTC-4, Eric Douglas wrote:
> On Friday, April 21, 2017 at 4:37:47 PM UTC-4, Rick C. Hodgin wrote:
> > 
> > Do you feel so inclined to write code to test that method out?
> > I only ask because you've been far more helpful than I would've
> > expected someone to be on Usenet. :-)  I plan on working on it
> > tonight.  I've only programmed in Java one time previously back
> > in 2011 on a project used to automate tests on hardware:
> 
> We won't "do your homework for you" but I do love a good puzzle.

I'm 47 years old.  I have written all of the bitmap algorithms
already in C/C++.  I'm very close to using JNI to complete this
task as well:

    http://www.libsf.org:8990/projects/LIB/repos/libsf/browse/source/vjr/source/bitmaps
    http://www.visual-freepro.org/wiki/index.php/Rick_C._Hodgin

> >     Office Productivity Benchmark
> >     https://github.com/RickCHodgin/opbm
> > 
> > A lot of code written mostly from May-July 2011.  I'm sure it
> > has lots of errors in it, but I was on my own in trying to do
> > everything.  I used Stack Overflow and the javadoc help files.
> > 
> > That one was written in NetBeans 8.0 I believe.
> > 
> I use Eclipse.  We have 2 developers in a small company.  I write
> all the Java.

I work predominately in Visual FoxPro and C/C++ for a company with
about 50 employees, though there are only seven in my division.

Thank you,
Rick C. Hodgin

[toc] | [prev] | [next] | [standalone]


#36511

FromKnute Johnson <nospam@rabbitbrush.frazmtn.com>
Date2017-04-22 11:28 -0500
Message-ID<odg05k$e1f$1@dont-email.me>
In reply to#36497
On 4/21/2017 10:28, Rick C. Hodgin wrote:
> I'm using JDK 1.8 on Linux.
>
> I have a PNG file which is ARGB when I load it in GIMP, and would like
> to obtain an array of int pixels to alter its contents directly from
> within my app.
>
> I am able to obtain byte[], but I don't know how to translate it to
> int[] for direct 4-byte access per pixel.
>
> I read on Stack Overflow that they aren't compatible unless the img
> created is ARGB as well, meaning the ImageIO.read(new File("myfile.png"))
> may have returned only a 24-bit RGB image, and not with the transparency
> layer/channel.  I also see on Stack Overflow that this may be a known
> bug as other people have had this same issue in the past.
>
> If true, how would I force it to read in and create it as an ARGB layer
> even if it doesn't think the alpha channel is there?  And if I cannot,
> do I read it in in whatever format it's in, create a second image of the
> same size but with 32-bit ARGB for the color depth, and then do some kind
> of BitBlt operation to paint the pixel bits into the other image?
>
> I come from a Win32 GDI and C/C++ background where I handle most of the
> low-level drawing through custom functions.  I'm not sure what the
> equivalent operation is in Java.
>
> -----
> I am basically trying to load an image, obtain an array to the raw
> pixel data so I can manipulate each pixel directly in various ways,
> including a colorize() algorithm, invert(), putBorder(), etc.
>
> Thank you,
> Rick C. Hodgin
>

What you want is a RescaleOp.  In test6 I create an image with three 
bars of red, green and blue.  Using test5 I invert the pixel values as 
you specified further down in these posts with a RescaleOp and the 
result is an image with three bars of cyan, magenta and yellow.

import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;

public class test6 {
     public static void main(String... args) throws Exception {
         BufferedImage img =
          new BufferedImage(640,480,BufferedImage.TYPE_INT_RGB);
         Graphics2D g = img.createGraphics();
         g.setColor(Color.RED);
         g.fillRect(0,0,213,480);
         g.setColor(Color.GREEN);
         g.fillRect(214,0,214,480);
         g.setColor(Color.BLUE);
         g.fillRect(428,0,213,480);
         g.dispose();
         ImageIO.write(img,"JPEG",new File("bars.jpg"));
     }
}

import java.awt.image.*;
import javax.imageio.*;
import java.io.*;

public class test5 {
     public static void main(String... args) throws Exception {
         BufferedImage img = ImageIO.read(new File("bars.jpg"));
         RescaleOp op = new RescaleOp(-1.0f,255f,null);
         BufferedImage chg = op.filter(img,null);
         ImageIO.write(chg,"JPEG",new File("bars2.jpg"));
     }
}


-- 

Knute Johnson

[toc] | [prev] | [next] | [standalone]


#36515

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2017-04-24 07:33 -0700
Message-ID<b700089d-64f7-4774-8adc-af45426847b6@googlegroups.com>
In reply to#36511
On Saturday, April 22, 2017 at 12:28:42 PM UTC-4, Knute Johnson wrote:
> On 4/21/2017 10:28, Rick C. Hodgin wrote:
> > I'm using JDK 1.8 on Linux.
> >
> > I have a PNG file which is ARGB when I load it in GIMP, and would like
> > to obtain an array of int pixels to alter its contents directly from
> > within my app.
> >
> > I am able to obtain byte[], but I don't know how to translate it to
> > int[] for direct 4-byte access per pixel.
> >
> > I read on Stack Overflow that they aren't compatible unless the img
> > created is ARGB as well, meaning the ImageIO.read(new File("myfile.png"))
> > may have returned only a 24-bit RGB image, and not with the transparency
> > layer/channel.  I also see on Stack Overflow that this may be a known
> > bug as other people have had this same issue in the past.
> >
> > If true, how would I force it to read in and create it as an ARGB layer
> > even if it doesn't think the alpha channel is there?  And if I cannot,
> > do I read it in in whatever format it's in, create a second image of the
> > same size but with 32-bit ARGB for the color depth, and then do some kind
> > of BitBlt operation to paint the pixel bits into the other image?
> >
> > I come from a Win32 GDI and C/C++ background where I handle most of the
> > low-level drawing through custom functions.  I'm not sure what the
> > equivalent operation is in Java.
> >
> > -----
> > I am basically trying to load an image, obtain an array to the raw
> > pixel data so I can manipulate each pixel directly in various ways,
> > including a colorize() algorithm, invert(), putBorder(), etc.
> >
> > Thank you,
> > Rick C. Hodgin
> >
> 
> What you want is a RescaleOp.  In test6 I create an image with three 
> bars of red, green and blue.  Using test5 I invert the pixel values as 
> you specified further down in these posts with a RescaleOp and the 
> result is an image with three bars of cyan, magenta and yellow.
> 
> import java.awt.*;
> import java.awt.image.*;
> import java.io.*;
> import javax.imageio.*;
> 
> public class test6 {
>      public static void main(String... args) throws Exception {
>          BufferedImage img =
>           new BufferedImage(640,480,BufferedImage.TYPE_INT_RGB);
>          Graphics2D g = img.createGraphics();
>          g.setColor(Color.RED);
>          g.fillRect(0,0,213,480);
>          g.setColor(Color.GREEN);
>          g.fillRect(214,0,214,480);
>          g.setColor(Color.BLUE);
>          g.fillRect(428,0,213,480);
>          g.dispose();
>          ImageIO.write(img,"JPEG",new File("bars.jpg"));
>      }
> }
> 
> import java.awt.image.*;
> import javax.imageio.*;
> import java.io.*;
> 
> public class test5 {
>      public static void main(String... args) throws Exception {
>          BufferedImage img = ImageIO.read(new File("bars.jpg"));
>          RescaleOp op = new RescaleOp(-1.0f,255f,null);
>          BufferedImage chg = op.filter(img,null);
>          ImageIO.write(chg,"JPEG",new File("bars2.jpg"));
>      }
> }

Is this for the color invert operation?  I notice it creates a new
BufferedImage.  Is there a way to apply the operation on the bits
within the original image directly?

Thank you,
Rick C. Hodgin

[toc] | [prev] | [next] | [standalone]


#36517

FromEric Douglas <e.d.programmer@gmail.com>
Date2017-04-24 08:04 -0700
Message-ID<6b44223f-7bc1-4093-9052-2eb253c8abbb@googlegroups.com>
In reply to#36515
On Monday, April 24, 2017 at 10:34:16 AM UTC-4, Rick C. Hodgin wrote:
> > import java.awt.*;
> > import java.awt.image.*;
> > import java.io.*;
> > import javax.imageio.*;
> > 
> > public class test6 {
> >      public static void main(String... args) throws Exception {
> >          BufferedImage img =
> >           new BufferedImage(640,480,BufferedImage.TYPE_INT_RGB);
> >          Graphics2D g = img.createGraphics();
> >          g.setColor(Color.RED);
> >          g.fillRect(0,0,213,480);
> >          g.setColor(Color.GREEN);
> >          g.fillRect(214,0,214,480);
> >          g.setColor(Color.BLUE);
> >          g.fillRect(428,0,213,480);
> >          g.dispose();
> >          ImageIO.write(img,"JPEG",new File("bars.jpg"));
> >      }
> > }
> > 
> > import java.awt.image.*;
> > import javax.imageio.*;
> > import java.io.*;
> > 
> > public class test5 {
> >      public static void main(String... args) throws Exception {
> >          BufferedImage img = ImageIO.read(new File("bars.jpg"));
> >          RescaleOp op = new RescaleOp(-1.0f,255f,null);
> >          BufferedImage chg = op.filter(img,null);
> >          ImageIO.write(chg,"JPEG",new File("bars2.jpg"));
> >      }
> > }
> 
> Is this for the color invert operation?  I notice it creates a new
> BufferedImage.  Is there a way to apply the operation on the bits
> within the original image directly?
> 
> Thank you,
> Rick C. Hodgin

test6 creates a dummy image, the input for test5, which just modifies an existing image.

[toc] | [prev] | [next] | [standalone]


#36519

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2017-04-24 08:17 -0700
Message-ID<0ed9258a-3395-4440-8793-b46427df4664@googlegroups.com>
In reply to#36511
On Saturday, April 22, 2017 at 12:28:42 PM UTC-4, Knute Johnson wrote:
> On 4/21/2017 10:28, Rick C. Hodgin wrote:
> > I'm using JDK 1.8 on Linux.
> >
> > I have a PNG file which is ARGB when I load it in GIMP, and would like
> > to obtain an array of int pixels to alter its contents directly from
> > within my app.
> >
> > I am able to obtain byte[], but I don't know how to translate it to
> > int[] for direct 4-byte access per pixel.
> >
> > I read on Stack Overflow that they aren't compatible unless the img
> > created is ARGB as well, meaning the ImageIO.read(new File("myfile.png"))
> > may have returned only a 24-bit RGB image, and not with the transparency
> > layer/channel.  I also see on Stack Overflow that this may be a known
> > bug as other people have had this same issue in the past.
> >
> > If true, how would I force it to read in and create it as an ARGB layer
> > even if it doesn't think the alpha channel is there?  And if I cannot,
> > do I read it in in whatever format it's in, create a second image of the
> > same size but with 32-bit ARGB for the color depth, and then do some kind
> > of BitBlt operation to paint the pixel bits into the other image?
> >
> > I come from a Win32 GDI and C/C++ background where I handle most of the
> > low-level drawing through custom functions.  I'm not sure what the
> > equivalent operation is in Java.
> >
> > -----
> > I am basically trying to load an image, obtain an array to the raw
> > pixel data so I can manipulate each pixel directly in various ways,
> > including a colorize() algorithm, invert(), putBorder(), etc.
> >
> > Thank you,
> > Rick C. Hodgin
> >
> 
> What you want is a RescaleOp.  In test6 I create an image with three 
> bars of red, green and blue.  Using test5 I invert the pixel values as 
> you specified further down in these posts with a RescaleOp and the 
> result is an image with three bars of cyan, magenta and yellow.
> 
> import java.awt.*;
> import java.awt.image.*;
> import java.io.*;
> import javax.imageio.*;
> 
> public class test6 {
>      public static void main(String... args) throws Exception {
>          BufferedImage img =
>           new BufferedImage(640,480,BufferedImage.TYPE_INT_RGB);
>          Graphics2D g = img.createGraphics();
>          g.setColor(Color.RED);
>          g.fillRect(0,0,213,480);
>          g.setColor(Color.GREEN);
>          g.fillRect(214,0,214,480);
>          g.setColor(Color.BLUE);
>          g.fillRect(428,0,213,480);
>          g.dispose();
>          ImageIO.write(img,"JPEG",new File("bars.jpg"));
>      }
> }
> 
> import java.awt.image.*;
> import javax.imageio.*;
> import java.io.*;
> 
> public class test5 {
>      public static void main(String... args) throws Exception {
>          BufferedImage img = ImageIO.read(new File("bars.jpg"));
>          RescaleOp op = new RescaleOp(-1.0f,255f,null);
>          BufferedImage chg = op.filter(img,null);
>          ImageIO.write(chg,"JPEG",new File("bars2.jpg"));
>      }
> }

Would it be possible to do this?

import java.awt.*; 
import java.awt.image.*; 
import java.io.*; 
import javax.imageio.*; 

public class test6 { 
     public static void main(String... args) throws Exception { 
         RescaleOp op = new RescaleOp(-1.0f,255f,null); 
         BufferedImage img = 
          new BufferedImage(640,480,BufferedImage.TYPE_INT_RGB); 
         Graphics2D g = img.createGraphics(); 
         g.setColor(Color.RED); 
         g.fillRect(0,0,213,480); 
         g.setColor(Color.GREEN); 
         g.fillRect(214,0,214,480); 
         g.setColor(Color.BLUE); 
         g.fillRect(428,0,213,480); 
         g.dispose(); 

===> Something like this, where the input img bits are updated directly:
         img = op.filter(img,null); 
         // Maintain img, now altered, as it was before
     }
}

That's what I'm trying to do with my algorithms.  Receive an existing
image and then process it in some way which directly updates its bits
without copying or creating a new image for output in the process.

Thank you,
Rick C. Hodgin

[toc] | [prev] | [next] | [standalone]


#36524

FromKnute Johnson <nospam@rabbitbrush.frazmtn.com>
Date2017-04-24 11:25 -0500
Message-ID<odl8oh$9ku$1@dont-email.me>
In reply to#36519
On 4/24/2017 10:17, Rick C. Hodgin wrote:
> Would it be possible to do this?
>
> import java.awt.*;
> import java.awt.image.*;
> import java.io.*;
> import javax.imageio.*;
>
> public class test6 {
>      public static void main(String... args) throws Exception {
>          RescaleOp op = new RescaleOp(-1.0f,255f,null);
>          BufferedImage img =
>           new BufferedImage(640,480,BufferedImage.TYPE_INT_RGB);
>          Graphics2D g = img.createGraphics();
>          g.setColor(Color.RED);
>          g.fillRect(0,0,213,480);
>          g.setColor(Color.GREEN);
>          g.fillRect(214,0,214,480);
>          g.setColor(Color.BLUE);
>          g.fillRect(428,0,213,480);
>          g.dispose();
>
> ===> Something like this, where the input img bits are updated directly:
>          img = op.filter(img,null);
>          // Maintain img, now altered, as it was before
>      }
> }
>
> That's what I'm trying to do with my algorithms.  Receive an existing
> image and then process it in some way which directly updates its bits
> without copying or creating a new image for output in the process.
>
> Thank you,
> Rick C. Hodgin

Yes however I'm pretty sure that if you use null as the second argument 
to BufferredImageOp.filter that it creates a new BufferedImage.  I think 
if you put the same reference in the call to filter it is the same image 
modified in place.

import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;

public class test6 {
     public static void main(String... args) throws Exception {
         BufferedImage img =
          new BufferedImage(640,480,BufferedImage.TYPE_INT_RGB);
         Graphics2D g = img.createGraphics();
         g.setColor(Color.RED);
         g.fillRect(0,0,213,480);
         g.setColor(Color.GREEN);
         g.fillRect(213,0,214,480);
         g.setColor(Color.BLUE);
         g.fillRect(427,0,213,480);
         g.dispose();

         RescaleOp op = new RescaleOp(-1.0f,255f,null);
         BufferedImage gmi = op.filter(img,img);
         System.out.println(gmi.equals(img));
     }
}

In this case the output is true.  If you put null in the second argument 
the output is false.  I don't know if it is any faster, the cost of 
creating a small BufferedImage is not that great.


-- 

Knute Johnson

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web