Page 1 of 1

Save BitMap

Posted: Tue Mar 06, 2018 4:42 am
by mritter0
I am trying to save a BitMapClass BitMap, but am not having much luck.

I am using DataTypes to load and scale the image and end up with this, which displays correctly:

Code: Select all

	if (!(Img=IIntuition->NewObject(BitMapClass,NULL,
		BITMAP_BitMap,							ScaleBM,
		BITMAP_Width,							ScaleWidth,
		BITMAP_Height,							ScaleHeight,
		BITMAP_HasAlpha,						TRUE,
		BITMAP_Screen,							DefaultPubScreen,
		BITMAP_Precision,						PRECISION_EXACT,
		BITMAP_Masking,							TRUE,
	TAG_DONE)))
Now I want to save it. I am close, but all I get is a grey box. And the depth always says 4, not 32.

Code: Select all


SaveBitMap(Img,ScaleWidth,ScaleHeight,"RAM:Scale.png");


BOOL
SaveBitMap(Object *Obj,uint32 Width,uint32 Height,STRPTR Dest)
{
	Object *dto=NULL;
	struct BitMapHeader *bmhd;
	struct BitMap					*BM=NULL;

	if (!(dto = IDataTypes->NewDTObject(NULL,
		DTA_SourceType,DTST_RAM,
//		DTA_GroupID,GID_PICTURE,
		DTA_BaseName,"png",
	TAG_DONE)))
		return(FALSE);

	if (IDataTypes->GetDTAttrs(dto,
		PDTA_BitMapHeader,&bmhd,
	TAG_DONE))
	{
		bmhd->bmh_Left = 0;
		bmhd->bmh_Top = 0;
		bmhd->bmh_Width = Width;
		bmhd->bmh_Height = Height;
		bmhd->bmh_Depth = 32;
	}

	IDataTypes->SetDTAttrs(dto,NULL,NULL,
		PDTA_SourceMode,PMODE_V43,
		DTA_NominalHoriz,Width,
		DTA_NominalVert,Height,
	TAG_DONE);

	IIntuition->GetAttrs(Obj,
		BITMAP_BitMap,							&BM,
	TAG_DONE);

	IIntuition->IDoMethod(dto, PDTM_WRITEPIXELARRAY, BM, PBPAFMT_ARGB, (Width*4)*Height, 0, 0, Width, Height);

	if (IDataTypes->SaveDTObjectA(dto,NULL,NULL,Dest,
		DTWM_RAW,								FALSE,
	NULL))
		error=0;
	else
		error=IDOS->IoErr();

	if (dto)
		IDataTypes->DisposeDTObject(dto);

	return(TRUE);
}
I don't think I am handling the BITMAP_BitMap,&BM, correctly in the Intuition->IDoMethod() call.

It saves it as a PNG.

What am I doing wrong?

Re: Save BitMap

Posted: Tue Mar 06, 2018 4:40 pm
by TSK
You'll have to convert the bitmap to a RGB array first and use that in IDoMethod call. Also the fifth parameter in the IDoMethod call is row size and not size of the whole area.

Code: Select all

 APTR tempbuffer=NULL;
 int32 err=0;

      tempbuffer=IExec->AllocVecTags(4*Width*Height,AVT_Type,MEMF_PRIVATE,AVT_ClearWithValue,0,TAG_DONE); 
      if (tempbuffer!=NULL)
      {
       err=IGraphics->BltBitMapTags(BLITA_SrcType,BLITT_BITMAP,BLITA_Source,BM,
                                    BLITA_SrcX,sbrect->MinX,BLITA_SrcY,sbrect->MinY,
                                    BLITA_DestType,BLITT_ARGB32,BLITA_Dest,tempbuffer,
                                    BLITA_Width,Width,BLITA_Height,Height,
                                    BLITA_DestBytesPerRow,Width*4,
                                    TAG_DONE);

       IIntuition->IDoMethod(dto,PDTM_WRITEPIXELARRAY,tempbuffer,PBPAFMT_ARGB,Width*4,0,0,Width,Height);

       IExec->FreeVec(tempbuffer);
      }
Also I'm using DTWM_IFF,FALSE in SaveDTObject() call. It saves as IFF-ILBM. I don't know if saving works with any other picture format.

Re: Save BitMap

Posted: Tue Mar 06, 2018 7:10 pm
by mritter0
That's what I was missing. Thank you.