[OpenJDK 2D-Dev] [9] Review request for 8152309 Seamless way of using image filters with multi-resolution images

Alexander Scherbatiy alexandr.scherbatiy at oracle.com
Wed Apr 20 20:46:43 UTC 2016


On 20/04/16 00:08, Phil Race wrote:
> I've gone up and down the API (and most of the implementation)
>
> ResolutionVariantItem is really only used in the public API in one 
> place :-
>
> ImageProducer defines :-
>
> +    default List<ResolutionVariantItem<ImageProducer>> 
> getResolutionVariantItems() {
> +        return Arrays.asList(new ResolutionVariantItem<>(this, 1, 1));
>
>
> The sort-of second place is that FilteredImageSource over-rides this.
> The rest is the internal uses of the class (and its definition of course)
>
> So do we need such a generic sounding API class for this one case, (or
> are there other API-level uses?) and  is there a different approach 
> which avoid the new class entirely ?

   The ResolutionVariantItem class in this case is used to provide scale 
factors for the ImageFilter and MediaTracker.
   If we want to avoid this class it is necessary to understand from 
which place these scale factors can be obtained.

   The MultiResolutionImage has just getResolutionVariant(width, height) 
method which allows to provide an image either from a set of resolution 
variants or just generating an image with requested size.

   It seems that generation an image for requested size is not an option 
for multi-resolution Toolkit image just because it can be loaded by 
MediaTracker.

    MediaTracker.addImage(Image, id, width, height) method needs to load 
all resolution variants from the provided multi-resolution image. First 
it means that there should be finite number of them. The second is that 
for passed width and height argument it needs to calculate size for the 
resolution variants which are not loaded yet.
   This is the first place where the scale factors need to be provided 
with resolution variant:
      MediaTracker.addImage(mriImage, id, w, h) -> 
MediaTracker.addImage(resolutionVariant, id, w * rvScaleX, h * rvScaleY)


   The second place where the resolution variant scales are used is 
SunGraphics2D.drawImage() method when it draws a multi-resoltion image 
with an applied filter.

         Image mrImage = // create a multi-resolution image
         ImageProducer filteredImageSource = new 
FilteredImageSource(mrImage.getSource(), filter);
         Image filteredImage = toolkit.createImage(filteredImageSource);

  SunGraphics2D.drawImage() calls getResolutionVariant(mrImage, ...) 
method to get a resolution variant with the requested destination width 
and height to draw it. The resolution variant in this case is just a 
ToolkitImage which source is FilteredImageSource an filter is a scaled 
filter:
     toolkit.createImage(new 
FilteredImageSource(resulutionVariant.getSource(), 
filter.getScaledFilterInstance(scaleX, scaleY)))

   And the question is where the the scale factors can be obtained for 
this case?

   If there are others way to provide scale factors for the described 
cases it will allow to not use new classes like ResolutionVariantItem.

   Thanks,
   Alexandr.

>
> Assuming ResolutionVariantItem is the right name - and design - it
> seems like it could use a bit more class javadoc, even if it is basically
> a bag to hold a few things.
>
> There are few formatting/typo things I noticed but no point in talking 
> about
> those until the rest is near conclusion.
>
> -phil.
>
> On 04/05/2016 07:30 AM, Alexander Scherbatiy wrote:
>>
>> Hello,
>>
>> Could you review the fix:
>>   bug: https://bugs.openjdk.java.net/browse/JDK-8152309
>>   webrev: http://cr.openjdk.java.net/~alexsch/8152309/webrev.00
>>
>>
>>   The purpose of the fix is to allow to apply an image filter for a 
>> multi-resolution image to get new multi-resolution image so the code 
>> below works without changes:
>>     ----------
>>     Image mrImage = getMultiResolutionImage();
>>     ImageProducer mriProducer = new 
>> FilteredImageSource(mrImage.getSource(), new CropImageFilter(x, y, w, 
>> h));
>>     Image filteredMRImage = 
>> Toolkit.getDefaultToolkit().createImage(mriProducer);
>>     ----------
>>
>>
>>   The Image producer needs to be updated to contain a set of 
>> resolution-variant image producers. It can be done introducing a new 
>> MultiResolution[Image]Producer interface. However, the 
>> FilteredImageSource which takes an original image producer as a 
>> constructor argument needs to be declared as 
>> MultiResolution[Image]Producer even for ordinary image producers.
>> I chose to add the getRVProducers() method directly to the 
>> ImageProducer interface.
>>
>> The option to add a method which request a resolution variant 
>> producer for the given image size (getRVProducer(width, height) ) 
>> seems is not possible because the result multi-resolution image can 
>> be loaded by a MediaTracker which can load only finite number of 
>> resolution variants.
>>
>> Applying an image filter to resolution-variant producers requires to 
>> scale filters which use fixed image size (like CropImageFilter and 
>> ReplicateScaleFilter).
>> There should be a way to get a scaled filter using the original one. 
>> The resolution variant image producer need to provide necessary scale 
>> factors for the used filter.
>> To do that getScaledFilterInstance(scaleX, scaleY) method is added to 
>> the ImageFilter and public ResolutionVariantItem class which can hold 
>> image or image producer with associated scale factors is introduced.
>>
>> There is an interesting problem in SunGraphics2D where a 
>> multi-resolution image size is requested. To do that it is necessary 
>> to have an image observer which needs to redirect calls to the base 
>> image observer. The resolution variant observer needs to know scale 
>> factors to recalculate given [x, y, width, height] values. The scale 
>> factors are provided by toolkit multi-resolution image but for non 
>> toolkit multi-resolution images they need to be calculated dividing a 
>> rv-image size to base image size. It looks like a closed loop when to 
>> know scale factors it needs to get a rv-image size but for this it is 
>> necessary to use an image observer which requires scale factors.
>> The current fix just divides rv-image size to base image size for non 
>> toolkit multi-resolution images to get scale factors .
>>
>>   Thanks,
>>   Alexandr.
>>
>




More information about the 2d-dev mailing list